package com.xhwl.data.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Joiner;
import com.vdurmont.emoji.EmojiParser;
import com.xhwl.common.dto.auth.AuthenticationDTO;
import com.xhwl.common.dto.auth.LoginDTO;
import com.xhwl.common.dto.cent.sdata.*;
import com.xhwl.common.dto.detection.CompositeDetectionDTO;
import com.xhwl.common.enums.CodeEnum;
import com.xhwl.common.enums.LogOperationTypeEnum;
import com.xhwl.common.enums.ModuleTypeEnum;
import com.xhwl.common.enums.OperationTypeEnum;
import com.xhwl.common.enums.OrganizationTypeEnum;
import com.xhwl.common.enums.ThirdAccountTypeEnum;
import com.xhwl.common.enums.config.BusinessType;
import com.xhwl.common.enums.config.InitializeEnum;
import com.xhwl.common.enums.config.InitializeRoleEnum;
import com.xhwl.common.enums.config.RoleTypeEnum;
import com.xhwl.common.enums.sdata.DevelopTypeEnum;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.exception.DataException;
import com.xhwl.common.pojo.AbstractAccount;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.OpenConfig;
import com.xhwl.common.pojo.cent.sdata.*;
import com.xhwl.common.pojo.cent.sdata.devplatform.Developer;
import com.xhwl.common.pojo.cent.sdata.personnel.Staff;
import com.xhwl.common.pojo.cent.sdata.personnel.StaffDTO;
import com.xhwl.common.pojo.cent.sdata.personnel.StaffOrganization;
import com.xhwl.common.query.OpenConfigQuery;
import com.xhwl.common.query.cent.AdminAccountQuery;
import com.xhwl.common.query.cent.sdata.*;
import com.xhwl.common.utils.CentDataVerifyUtil;
import com.xhwl.common.utils.ChkUtil;
import com.xhwl.common.utils.DataVerifyUtil;
import com.xhwl.common.utils.ThreadLocalUtil;
import com.xhwl.common.utils.ValidatorUtil;
import com.xhwl.common.vo.cent.sdata.AccountCriteria;
import com.xhwl.common.vo.cent.sdata.AccountDetailVO;
import com.xhwl.common.vo.cent.sdata.AccountSearchVO;
import com.xhwl.common.vo.cent.sdata.RoleDetailVO;
import com.xhwl.data.config.PwdConfig;
import com.xhwl.data.dao.*;
import com.xhwl.data.dao.devplatform.IDeveloperDao;
import com.xhwl.data.mq.producer.AccountProducer;
import com.xhwl.data.mq.producer.AccountPwdProducer;
import com.xhwl.data.pojo.AccountOperatorAuth;
import com.xhwl.data.service.*;
import com.xhwl.data.service.devplatform.IDeveloperService;
import com.xhwl.data.service.personal.IStaffOrganizationService;
import com.xhwl.data.service.personal.IStaffService;
import com.xhwl.data.util.Constant;
import com.xhwl.data.util.RedisUtils;
import com.xhwl.starter.detection.IDetectionService;
import com.xhwl.starter.log.LogTemplate;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * @description:
 * @author:
 * @create: 2020-11-25
 **/
@Service
public class AccountServiceImpl extends ServiceImpl<IAccountDao, Account> implements IAccountService {
    private static final Logger log = LoggerFactory.getLogger(AccountServiceImpl.class);
    private String DEFAULT_PWD = "xh123456@";
    private String REGISTER_TOURIST_ROLE_CODE = "TOURIST1";
    @Autowired
    IAccountProjectService accountProjectService;
    @Autowired
    IAccountOrganizationService accountOrganizationService;
    @Autowired
    private IEnterpriseProjectService enterpriseProjectService;
    @Autowired
    IAccountRoleService accountRoleService;
    @Autowired
    IEnterpriseService enterpriseService;
    @Autowired
    IEnterpriseDao enterpriseDao;
    @Autowired
    IRoleService roleService;
    @Autowired
    IProjectService projectService;
    @Autowired
    IProjectPermissionService projectPermissionService;
    @Autowired
    IRolePermissionService rolePermissionService;
    @Autowired
    IAdminAccountService adminAccountService;
    @Autowired
    IPermissionService permissionService;
    @Autowired
    IAccountService accountService;
    @Autowired
    IAccountRoleDao accountRoleDao;
    @Autowired
    IAccountProjectDao accountProjectDao;
    @Autowired
    IAccountDao accountDao;
    @Autowired
    IOrganizationDao organizationDao;
    @Autowired
    IProjectDao projectDao;
    @Autowired
    IAppDao appDao;
    @Autowired
    IAccountOrganizationDao accountOrganizationDao;
    @Autowired
    IMessageCodeService messageCodeService;
    @Autowired
    IOrganizationService organizationService;
    @Autowired
    IAccountOpenAuthService accountOpenAuthService;
    @Autowired
    RedisUtils redisUtils;
    @Autowired
    LogTemplate logTemplate;
    @Autowired
    AccountProducer accountProducer;
    @Autowired
    IRoleDao roleDao;
    @Autowired
    IAppService appService;
    @Autowired
    IOpenConfigService openConfigService;
    @Autowired
    IGroupAccountService groupAccountService;
    @Autowired
    private IAdminAccountDao adminAccountDao;
    @Autowired
    private IPermissionGroupService permissionGroupService;
    @Autowired
    IDeveloperDao developerDao;
    @Autowired
    IDetectionService detectionService;
    @Autowired
    IDeveloperService developerService;
    @Autowired
    private IOrganizationManagerService organizationManagerService;
    @Autowired
    private IStaffOrganizationService staffOrganizationService;
    @Autowired
    private IStaffService staffService;
    @Autowired
    private AccountPwdProducer accountPwdProducer;
    @Autowired
    private PwdConfig pwdConfig;
    /**
     * 动态获取用户组账号数据 （分页）
     *
     * @param page
     * @param groupAccountQuery
     * @return
     */
    @Override
    public Page<GroupAccountDTO> getGroupAccountDynamic(Page page, GroupAccountQuery groupAccountQuery) {
        Page<GroupAccountDTO> groupAccountDynamic = accountDao.getGroupAccountDynamic(page, groupAccountQuery);
        List<GroupAccountDTO> records = groupAccountDynamic.getRecords();
        List<Integer> accountIdsAll = records.stream().map(GroupAccountDTO::getId).collect(Collectors.toList());
        Set<Integer> accountIdsSet = new HashSet<>(accountIdsAll);
        List<Integer> commonInitializedRoles = roleService.getCommonInitializedRoles(Arrays.asList(groupAccountQuery.getIndustryId()));
        //转换账号-角色 信息map
        Map<Integer, Map<String, Object>> accountRoleInfoMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(accountIdsSet)) {
            accountRoleInfoMap = convertAccountRoleMap(new AccountQuery(), new ArrayList<>(accountIdsSet), commonInitializedRoles);
        }
        for (GroupAccountDTO groupAccountDTO : records) {
            Integer accountId = groupAccountDTO.getId();
            //角色信息填充
            if (accountRoleInfoMap.containsKey(accountId)) {
                Map<String, Object> roleInfoMap = accountRoleInfoMap.get(accountId);
                List<Integer> roleIds = (List<Integer>) roleInfoMap.get("roleIds");
                groupAccountDTO.setRoleIds(roleIds);
                groupAccountDTO.setRoleName((String) roleInfoMap.get("roleName"));
            }
        }
        return groupAccountDynamic;
    }

    /**
     * 根据登录名、业态类型、appId ,查询出该账户的账号信息、权限信息
     *
     * @param loginDTO
     * @return
     */
    @Override
    public AuthenticationDTO getCommonAccountInfo(LoginDTO loginDTO) {

        AccountQuery accountQuery = new AccountQuery();
        if (StringUtils.isNotEmpty(loginDTO.getLoginName())) {
            accountQuery.setLoginName(loginDTO.getLoginName());
        }
        if (StringUtils.isNotEmpty(loginDTO.getEmail())) {
            accountQuery.setEmail(loginDTO.getEmail());
        }
        if (StringUtils.isNotEmpty(loginDTO.getTelephone())) {
            accountQuery.setPhone(loginDTO.getTelephone());
        }
        if(null != loginDTO.getAccountId()){
            accountQuery.setId(loginDTO.getAccountId());
        }
        QueryWrapper<Developer> developerQueryWrapper = new QueryWrapper<>();
        developerQueryWrapper.select("id");
        if (StringUtils.isNotEmpty(loginDTO.getDevelopCode())) {
            developerQueryWrapper.eq("code", loginDTO.getDevelopCode());
            Developer developer = developerDao.selectOne(developerQueryWrapper);
            if (null == developer) {
                throw new DataException("开发者不存在");
            }
            accountQuery.setDevelopId(developer.getId());
        } else {
            // 默认的开发者
            developerQueryWrapper.eq("type", DevelopTypeEnum.DEFAULT.id);
            List<Developer> developers = developerDao.selectList(developerQueryWrapper);
            if (CollectionUtils.isEmpty(developers)) {
                throw new DataException("开发者不存在");
            }
            accountQuery.setDevelopId(developers.get(0).getId());
        }
        Account account = getAccount(null, accountQuery);
        if (Objects.isNull(account)) {
            log.warn("账号登录，接收到的参数，loginDTO={}", loginDTO.toString());
            throw new DataException("帐号不存在");
        }
        if (StringUtils.isNotEmpty(account.getName())) {
            String name = account.getName();
            account.setName(EmojiParser.parseToUnicode(name));
        }
        if (StringUtils.isNotEmpty(account.getNickname())) {
            String name = account.getNickname();
            account.setNickname(EmojiParser.parseToUnicode(name));
        }
        String appId = loginDTO.getAppId();
        String loginName = account.getLoginName();
        Short industryId = loginDTO.getIndustryId();
        App app = appService.getByAppId(appId);
        if (null == app) {
            log.warn("appId参数异常={}", appId);
            throw new DataException("appId参数异常");
        }
        account.setLoginName(loginName);
        account.setIndustryId(industryId);
        PermissionQuery permissionQuery = new PermissionQuery();
        permissionQuery.setAccountId(account.getId());
        permissionQuery.setAppIdPrimaryKey(app.getId());
        permissionQuery.setIndustryId(industryId);
        List<Permission> permissions = permissionService.getPermissionList(permissionQuery);
        AuthenticationDTO authenticationDTO = new AuthenticationDTO();
        BeanUtils.copyProperties(account, authenticationDTO);
        authenticationDTO.setUserId(account.getId());
        if (!CollectionUtils.isEmpty(permissions)) {
            authenticationDTO.setPermissionsCodeList(permissions.stream().map(Permission::getCode).collect(Collectors.toList()));
        }
        authenticationDTO.setUserId(account.getId()).setNickname(account.getNickname());
        authenticationDTO.setAppId(appId);
        authenticationDTO.setIndustryId(industryId);
        return authenticationDTO;
    }

    /**
     * 系统配置后台的admin账号 特殊处理  这个不需要进行角色权限管理查找，单独从AdminAccount表查找
     *
     * @param
     * @return
     */
    @Override
    public AuthenticationDTO getAdminAccountInfo(String loginName) {
        AdminAccount adminAccount = adminAccountService.findByLoginName(loginName);
        AuthenticationDTO authenticationDTO = new AuthenticationDTO();
        BeanUtils.copyProperties(adminAccount, authenticationDTO);
        authenticationDTO.setUserId(adminAccount.getId());
        return authenticationDTO;
    }

    @Override
    public AuthenticationDTO getAdminAccountInfoV2(AdminAccountQuery accountQuery) {
        QueryWrapper<AdminAccount> accountQueryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(accountQuery.getLoginName())) {
            accountQueryWrapper.eq("login_name", accountQuery.getLoginName());
        }
        if (StringUtils.isNotEmpty(accountQuery.getPhone())) {
            accountQueryWrapper.eq("phone", accountQuery.getPhone());
        }
        if (StringUtils.isNotEmpty(accountQuery.getEmail())) {
            accountQueryWrapper.eq("email", accountQuery.getEmail());
        }
        developerHandler(accountQuery, accountQueryWrapper);
        AdminAccount adminAccount = adminAccountService.getOne(accountQueryWrapper);
        if (null == adminAccount) {
            log.warn("后台账号不存在 ，loginName :{}   developId {}", accountQuery.getLoginName(), accountQuery.getDevelopId());
            return null;
        }
        AuthenticationDTO authenticationDTO = new AuthenticationDTO();
        BeanUtils.copyProperties(adminAccount, authenticationDTO);
        authenticationDTO.setUserId(adminAccount.getId());
        return authenticationDTO;
    }

    /**
     * 开发者code转id
     *
     * @param accountQuery
     * @param accountQueryWrapper
     */
    private void developerHandler(AdminAccountQuery accountQuery, QueryWrapper<AdminAccount> accountQueryWrapper) {
        // 如果没有传开发者code则默认取数据库第一个
        QueryWrapper<Developer> developerQueryWrapper = new QueryWrapper<>();
        developerQueryWrapper.select("id");
        if (StringUtils.isNotEmpty(accountQuery.getDevelopCode())) {
            developerQueryWrapper.eq("code", accountQuery.getDevelopCode());
        } else {
            // 默认的开发者
            developerQueryWrapper.eq("type", DevelopTypeEnum.DEFAULT.id);
        }
        Developer developer = developerDao.selectOne(developerQueryWrapper);
        if (null == developer) {
            throw new DataException("开发者不存在");
        }
        accountQuery.setDevelopId(developer.getId());
        accountQueryWrapper.eq("develop_id", accountQuery.getDevelopId());
    }

    @Override
    public AuthenticationDTO getAdminAccountByPhone(String phone) {
        QueryWrapper<AdminAccount> adminAccountQueryWrapper = new QueryWrapper<>();
        adminAccountQueryWrapper.eq("phone", phone);
        AdminAccount adminAccount = adminAccountDao.selectOne(adminAccountQueryWrapper);
        AuthenticationDTO authenticationDTO = new AuthenticationDTO();
        BeanUtils.copyProperties(adminAccount, authenticationDTO);
        authenticationDTO.setUserId(adminAccount.getId());
        return authenticationDTO;
    }


    /**
     * 重新设置密码
     * 默认密码重置为xh123456
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultJson resetPwd(Integer operateAccountId, Integer id) {
        RoleTypeEnum operateRoleType = roleService.getAccountRoleType(operateAccountId).getRoleTypeEnum();
        if (!(RoleTypeEnum.SUPPER_MANAGER.equals(operateRoleType)
                || RoleTypeEnum.ENT_MANAGER.equals(operateRoleType)
                || RoleTypeEnum.PRO_MANAGER.equals(operateRoleType))) {
            return ResultJson.fail("无重置密码权限");
        }
        Account account = new Account();
        account.setId(id);
        account.setIsLogged(false);
        //密码加密，默认密码重置为12345678
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        account.setPassword(bCryptPasswordEncoder.encode(DEFAULT_PWD));
        UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id);
        int effectNumUpdate = accountDao.update(account, updateWrapper);
        if (1 != effectNumUpdate) {
            throw new DataException("重置密码失败");
        }
        Account accountDb = findById(id);
        Account operateAccount = findById(operateAccountId);
        //记录操作日志
        accountLogRecord(operateAccount, LogOperationTypeEnum.UPDATE, "编辑账号" + "【" + accountDb.getLoginName() + "】");
        return ResultJson.success("重置成功");
    }

    /**
     * 初次登录-账号初试密码 修改 ，修改后把初次登录标识改为true
     *
     * @param id
     * @param pwd
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultJson modifyPwd(Integer id, String pwd) {
        if (null == id) {
            throw new DataException("缺少账号信息");
        }
        Account accountDb = findById(id);
        if (Objects.isNull(accountDb)) {
            throw new DataException("缺少账号信息");
        }
        if (StringUtils.isNotEmpty(accountDb.getLoginName()) && StringUtils.isNotEmpty(pwd)) {
            if (accountDb.getLoginName().equals(pwd)) {
                log.info("密码与用户名重复,账号id={}", id);
                throw new DataException("密码格式错误");
            }
        }
        //密码校验
        pwdConfig.passwordCheck(pwd);
        Account account = new Account();
        account.setId(id);
        account.setIsLogged(true);
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        //密码加密
        String pwdEncode = bCryptPasswordEncoder.encode(pwd);
        account.setPassword(pwdEncode);
        UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id);
        int effectNumUpdate = accountDao.update(account, updateWrapper);
        if (1 != effectNumUpdate) {
            throw new DataException("修改密码失败");
        }
        //修改密码成功后需要 删除redis缓存信息
        removeAccountAuthCache(id);
        // 推送修改后的新密码至kafka（明文）
        sendPwdToMQ(account, pwd);
        //记录操作日志
        accountLogRecord(accountDb, LogOperationTypeEnum.UPDATE, "编辑账号" + "【" + accountDb.getLoginName() + "】");
        return ResultJson.success("修改成功");
    }

    /**
     * 修改邮箱
     *
     * @param id
     * @param email
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultJson modifyEmail(Short industryId, Integer id, String email) {
        if (null == id) {
            return ResultJson.fail("缺少账号信息");
        }
        if (StringUtils.isEmpty(email)) {
            CentDataVerifyUtil.emailVerify(email);
        }

        Account account = new Account();
        account.setId(id);
        account.setEmail(email);
        account.setIndustryId(industryId);

        //个人信息唯一验证
        accountUnique(account);

        UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id);
        int effectNumUpdate = accountDao.update(account, updateWrapper);
        if (1 != effectNumUpdate) {
            return ResultJson.fail("修改邮箱失败");
        }
        Account accountDb = findById(id);
        //记录操作日志
        accountLogRecord(accountDb, LogOperationTypeEnum.UPDATE, "编辑账号" + "【" + accountDb.getLoginName() + "】");
        return ResultJson.success("修改成功");
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultJson editHeadImg(Integer id, String headImg) {
        if (StringUtils.isEmpty(headImg)) {
            return ResultJson.fail("缺少头像信息");
        }
        Account account = new Account();
        account.setId(id);
        account.setHeadImg(headImg);
        UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id);
        int effectNumUpdate = accountDao.update(account, updateWrapper);
        if (1 != effectNumUpdate) {
            throw new DataException("修改头像失败");
        }
        Account accountDb = findById(id);
        //记录操作日志
        accountLogRecord(accountDb, LogOperationTypeEnum.UPDATE, "编辑账号" + "【" + accountDb.getLoginName() + "】");
        return ResultJson.success("修改成功");
    }


    /**
     * 设置账号已登录状态
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultJson setLogged(Integer id) {
        if (null == id) {
            throw new DataException("缺少账号信息");
        }
        Account account = new Account();
        account.setId(id);
        account.setIsLogged(true);
        UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id);
        try {
            accountDao.update(account, updateWrapper);
        } catch (Exception e) {
            log.info("账号 id={}，已经设置登录状态为已登录 失败", id);
            return ResultJson.fail("设置已登录状态失败");
        }
        log.info("账号 id={}，已经设置登录状态为已登录 成功", id);
        return ResultJson.success("操作成功");
    }

    /**
     * 设置账号勾选了协议
     *
     * @param id
     * @return
     */
    @Override
    public ResultJson setProtocol(Integer id) {
        if (null == id) {
            throw new DataException("缺少账号信息");
        }
        Account account = new Account();
        account.setId(id);
        account.setIsProtocol(1);
        UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id);
        try {
            accountDao.update(account, updateWrapper);
        } catch (Exception e) {
            log.error("账号 id={}，设置已勾选协议状态 失败, 原因 {}", id, e.getMessage());
            return ResultJson.fail("设置已勾选协议状态失败");
        }
        log.info("账号 id={}，设置已勾选协议状态 成功", id);
        return ResultJson.success("操作成功");
    }

    /**
     * 账号密码的验证
     *
     * @param id
     * @param pwd
     * @return
     */
    @Override
    public ResultJson verifyPwd(Integer id, String pwd) {
        if (null == id) {
            throw new DataException("缺少账号信息");
        }
        if (StringUtils.isEmpty(pwd)) {
            throw new DataException("缺少密码数据");
        }
        //不允许 空格串和空数据
        if (DataVerifyUtil.isSpaceString(pwd)) {
            throw new DataException("密码不能为空");
        }
        Account account = accountDao.selectById(id);
        String pwdDb = account.getPassword();
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        boolean pwdMatchesResult = passwordEncoder.matches(pwd, pwdDb);
        if (pwdMatchesResult) {
            return ResultJson.success("密码验证通过");
        }
        return ResultJson.fail("密码有误");
    }

    /**
     * 修改个人信息
     *
     * @param account
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultJson modifyPersonalInfo(Account account) {
        Integer updateId = account.getId();
        if (null == updateId) {
            return ResultJson.fail("缺少账号信息");
        }
        Account accountInfo = accountDao.selectById(updateId);
        account.setDevelopId(accountInfo.getDevelopId());
        if (Objects.isNull(accountInfo)) {
            return ResultJson.fail("不存在此个人信息");
        }
        if (StringUtils.isNotEmpty(account.getName())) {
            String nameCovert = EmojiParser.parseToAliases(account.getName());
            account.setName(nameCovert);
        }
        if (StringUtils.isNotEmpty(account.getNickname())) {
            String nickNameCovert = EmojiParser.parseToAliases(account.getNickname());
            account.setNickname(nickNameCovert);
        }

        //个人信息唯一验证
        accountUnique(account);
        UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", updateId);
        int effectNumUpdate = accountDao.update(account, updateWrapper);
        if (1 != effectNumUpdate) {
            throw new DataException("修改个人信息失败");
        }
        Account accountDb = findById(updateId);
        //记录操作日志
        accountLogRecord(accountDb, LogOperationTypeEnum.UPDATE, "编辑账号" + "【" + accountDb.getLoginName() + "】");
        return ResultJson.success("修改成功");
    }

    /**
     * 根据角色id 查找账号id列表
     *
     * @param roleId
     * @return
     */
    @Override
    public List<Integer> getAccountIdListByRoleId(Integer roleId) {
        if (null == roleId) {
            throw new DataException("缺少角色信息");
        }
        QueryWrapper<AccountRole> accountRoleQueryWrapper = new QueryWrapper<>();
        accountRoleQueryWrapper.select("account_id");
        accountRoleQueryWrapper.eq("role_id", roleId);
        List<AccountRole> accountRoleList = accountRoleDao.selectList(accountRoleQueryWrapper);
        List<Integer> accountIdList = accountRoleList.stream().map(AccountRole::getAccountId).collect(Collectors.toList());
        return accountIdList;
    }

    /**
     * 获取业态下的内置角色list
     *
     * @param industryId
     * @return
     */
    @Override
    public List<Map<String, Object>> getCommonInitRoleEnumList(Short industryId) {
        if (null == industryId) {
            throw new DataException("缺少业态信息");
        }
        List<Map<String, Object>> list = new ArrayList<>();
        for (InitializeRoleEnum initializeRoleEnum : InitializeRoleEnum.values()) {
            Map<String, Object> map = new HashMap<>();
            if (industryId == initializeRoleEnum.getIndustryId()) {
                map.put("id", initializeRoleEnum.getId());
                map.put("enumName", initializeRoleEnum.name());
                map.put("roleName", initializeRoleEnum.getName());
                list.add(map);
            }
        }
        return list;
    }

    /**
     * 移除账号的某个角色（关联数据）
     *
     * @param accountId
     * @param roleId
     * @return
     */
    @Override
    public ResultJson removeAssignRole(Integer accountId, Integer roleId) {
        if (null == accountId) {
            throw new DataException("缺少账号信息");
        }
        if (null == roleId) {
            throw new DataException("缺少角色信息");
        }
        //先查询当前账号是否只有一个角色，如果
        // 只有一个不能移除
        List<Integer> roleIds = accountRoleService.findRoleIdByAccountId(accountId);
        if (CollectionUtils.isEmpty(roleIds)) {
            return ResultJson.fail("该账号无任何角色关联数据,移除失败");
        }
        if (1 == roleIds.size()) {
            return ResultJson.fail("该用户只剩最后一个角色身份，无法移除");
        }
        Role removeRole = roleService.getRoleById(roleId);
        Integer removeRoleProId = removeRole.getProjectId();
        Integer removeRoleEntId = removeRole.getEnterpriseId();
        //移除账号、角色关联关系
        removeRole(accountId, Arrays.asList(roleId));
        log.info("账号、角色关联关系移除成功，账号id={}，角色id={}", accountId, roleId);
        //需要检测当前角色所属项目
        List<Integer> roleIdsNow = accountRoleService.findRoleIdByAccountId(accountId);
        RoleQuery roleQuery = new RoleQuery();
        roleQuery.setIdList(roleIdsNow);
        List<Integer> commonInitializedRoles = roleService.getCommonInitializedRoles(null);
        for (Integer id : commonInitializedRoles) {
            if (roleIdsNow.contains(id)) {
                roleQuery.setNeedCommonInitialized(true);
            }
        }
        List<Role> roleInfoList = roleService.getRoleList(null, roleQuery);
        Set<Integer> entIdSet = new HashSet<>();
        Set<Integer> proIdSet = new HashSet<>();
        for (Role r : roleInfoList) {
            if (null != r.getEnterpriseId()) {
                entIdSet.add(r.getEnterpriseId());
            }
            if (null != r.getProjectId()) {
                proIdSet.add(r.getProjectId());
            }
        }
        List<Integer> projectIds = new ArrayList<>(proIdSet);
        List<Integer> enterpriseIds = new ArrayList<>(entIdSet);
        //校验是否需要移除账号-项目 、账号-组织（项目级）数据  (项目id主导)
        removeAccountProject(accountId, removeRoleProId, projectIds);
        //校验是否需要移除账号-企业、账号-组织（企业级）数据  (企业id主导)
        removeAccountEnterprise(accountId, removeRoleProId, removeRoleEntId, enterpriseIds);
        Account account = findById(accountId);
        //记录操作日志
        accountLogRecord(null, LogOperationTypeEnum.UPDATE, "编辑账号" + "【" + account.getLoginName() + "】");
        return ResultJson.success("移除成功");
    }


    /**
     * 修改 账号内置角色/项目关系数据
     *
     * @param operateAccount
     * @param account
     * @param enterpriseIds
     * @param projectIds
     * @param roleIds
     * @return
     */
    @Override
    public ResultJson updateCommonInitializeRole(Account operateAccount, Account account, List<Integer> enterpriseIds, List<Integer> projectIds, List<Integer> roleIds) {
        if (Objects.isNull(account.getId())) {
            throw new DataException("缺少账号数据");
        }
        //获取当前登录操作账号的角色身份
        RoleTypeEnum operateRoleType = roleService.getAccountRoleType(operateAccount.getId()).getRoleTypeEnum();
        //查出需要修改的账号的角色身份
        RoleTypeEnum updateAccountRoleType = roleService.getAccountRoleType(account.getId()).getRoleTypeEnum();
        Boolean checkResult = updateAccountCheck(account.getIndustryId(), operateRoleType, updateAccountRoleType);
        if (!checkResult) {
            return ResultJson.fail("修改失败,权限不足");
        }
        //操作人的企业list
//        List<Enterprise> enterpriseList = enterpriseService.list(null, operateAccount);
//        if (CollectionUtils.isEmpty(enterpriseList)) {
//            throw new DataException("当前操作人无权限操作任何企业");
//        }
//        List<Integer> enterpriseIdList = enterpriseList.stream().map(e -> e.getId()).collect(Collectors.toList());
        //操作人的项目list
//        QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
//        projectQueryWrapper.in("enterprise_id", enterpriseIdList);
//        List<Project> projectList = projectDao.selectList(projectQueryWrapper);
//        if (CollectionUtils.isEmpty(projectList)) {
//            throw new DataException("当前操作人无权限操作任何项目");
//        }
        //手机号校验
        //不允许 空格串和空数据
        if (StringUtils.isNotEmpty(account.getPhone())) {
            CentDataVerifyUtil.phoneVerify(account.getPhone());
        }
        //账号登录名不允许包含空格
        if (StringUtils.isNotEmpty(account.getLoginName())) {
            CentDataVerifyUtil.loginNameVerify(account.getLoginName());
        }
        //填充加密后的密码
        if (Objects.nonNull(account.getPassword())) {
            CentDataVerifyUtil.pwdVerify(account.getPassword());
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            String pwdEncode = bCryptPasswordEncoder.encode(account.getPassword());
            account.setPassword(pwdEncode);
        }
        Integer accountId = account.getId();
        Account accountExist = accountDao.selectById(accountId);
        if (Objects.isNull(accountExist)) {
            log.info("检测到账号数据不存在，id={}", accountId);
            throw new DataException("账号数据不存在");
        }
        //业态下，手机号 唯一 / 账号 唯一
        accountUnique(account);
        if (StringUtils.isNotEmpty(account.getName())) {
            String nameCovert = EmojiParser.parseToAliases(account.getName());
            account.setName(nameCovert);
        }
        if (StringUtils.isNotEmpty(account.getNickname())) {
            String nickNameCovert = EmojiParser.parseToAliases(account.getNickname());
            account.setNickname(nickNameCovert);
        }
        //先更新账号信息
        UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", accountId);
        int effectNumUpdate = accountDao.update(account, updateWrapper);
        if (effectNumUpdate != 1) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new DataException("更新账号数据失败");
        }
        //再更新当前账号的内置角色关联关系， 采取删除后再新增
        Short industryId = accountExist.getIndustryId();
        List<Integer> commonInitializedRoles = roleService.getCommonInitializedRoles(Arrays.asList(industryId));
        //先删除当前账号与这些角色的关联关系
        accountRoleService.deleteAccountRole(Arrays.asList(accountId), commonInitializedRoles);
        //再新增当前账号与传入的这些角色的关联关系
        accountRoleService.insertAccountRole(accountId, roleIds);
        //处理项目问题
        List<AccountProject> projectsDb = accountProjectService.findByProjectIds(accountId, null);
        List<Integer> projectIdsDb = projectsDb.stream().map(AccountProject::getId).collect(Collectors.toList());
        List<Integer> needAddProIds = new ArrayList<>();
        for (Integer needAddProId : projectIds) {
            if (!projectIdsDb.contains(needAddProId)) {
                needAddProIds.add(needAddProId);
            }
        }
        //针对不跨企业作校验
        //把当前账号关联的企业数据查出来，比较需要插入的企业数据，判断是否有不对称数据  兼容业态后台不做校验，没有拦截多企业错乱数据
        if (!CollectionUtils.isEmpty(needAddProIds)) {
            QueryWrapper<Project> projectQueryDbWrapper = new QueryWrapper<>();
            projectQueryDbWrapper.in("id", needAddProIds);
            List<Project> projects = projectDao.selectList(projectQueryDbWrapper);
            if (!CollectionUtils.isEmpty(projects)) {
                List<Integer> resultEntIdList = projects.stream().map(Project::getEnterpriseId).collect(Collectors.toList());
                if (crossEnterpriseVerify(resultEntIdList, accountId)) {
                    return ResultJson.fail("修改失败,当前账号已经关联其他企业，不允许跨企业账号");
                }
            }
        }
        //新增 账号-项目关联表 及 账号-组织关联表
        dealAccountProjectOrg(accountId, needAddProIds);
        //维护  账号、 业态角色 、 项目 之间的关系
        try {
            holdAccountInitRole(account, projectIds, roleIds, OperationTypeEnum.UPDATE.getType());
        } catch (Exception e) {
            log.info("维护账号业态角色与项目 之间的关系出现异常accountId={}，projectIds={}，roleIds={}", account.getId(), projectIds.toString(), roleIds);
        }
        Account accountDb = findById(account.getId());
        //记录操作日志
        accountLogRecord(operateAccount, LogOperationTypeEnum.UPDATE, "编辑账号" + "【" + accountDb.getLoginName() + "】");
        return ResultJson.success("修改成功");
    }

    /**
     * 处理账号、项目、组织 关联数据
     *
     * @param accountId
     * @param needAddProIds
     */
    public void dealAccountProjectOrg(Integer accountId, List<Integer> needAddProIds) {
        if (!CollectionUtils.isEmpty(needAddProIds)) {
            List<AccountProject> projectsCheck = accountProjectService.findByProjectIds(accountId, needAddProIds);
            List<Integer> projectIdsCheck = projectsCheck.stream().map(AccountProject::getId).collect(Collectors.toList());
            List<Integer> needAddResultIds = new ArrayList<>();
            if (CollectionUtils.isEmpty(projectIdsCheck)) {
                needAddResultIds.addAll(needAddProIds);
            } else {
                List<Integer> filterIds = new ArrayList<>();
                for (Integer needIds : needAddProIds) {
                    if (!projectIdsCheck.contains(needIds)) {
                        filterIds.add(needIds);
                    }
                }
                needAddResultIds.addAll(filterIds);
            }
            QueryWrapper<AccountProject> deleteWrapper = new QueryWrapper<>();
            deleteWrapper.eq("account_id", accountId);
            deleteWrapper.in("project_id", needAddResultIds);
            log.info("现在移除操作的项目id={}", needAddResultIds.toString());
            accountProjectService.remove(deleteWrapper);
            log.info("现在新增操作的项目id={}", needAddResultIds.toString());
            accountProjectService.insert(accountId, needAddResultIds);
            saveAccountOrganizationProjectIds(needAddResultIds, accountId);
        }
    }


    /**
     * 获取账号列表 根据角色分组
     *
     * @param accountRoleQuery
     * @return
     */
    @Override
    public ResultJson listGroupByRole(AccountRoleQuery accountRoleQuery) {
        Short industryId = accountRoleQuery.getIndustryId();
        List<Integer> projectIds = accountRoleQuery.getProjectIdList();
        Boolean needCommonInitialized = accountRoleQuery.getNeedCommonInitialized();
        Boolean needSuper = accountRoleQuery.getNeedSuper();
        List<Integer> roleIdList = new ArrayList<>();
        List<RoleDetailDTO> roleAccountDetailList = new ArrayList<>();
        //只需要内置角色，直接单独获取内置角色信息
        if (accountRoleQuery.getOnlyNeedCommonInit()) {
            List<Role> commonInitRoles = roleService.getCommonInitRoleDetail(Arrays.asList(industryId));
            for (Role r : commonInitRoles) {
                RoleDetailDTO roleDetail = new RoleDetailDTO();
                BeanUtils.copyProperties(r, roleDetail);
                roleAccountDetailList.add(roleDetail);
                roleIdList.add(r.getId());
            }
        } else {
            roleAccountDetailList = roleService.getCurrentProjectRelatedList(industryId, projectIds, needCommonInitialized, needSuper);
            roleIdList = roleAccountDetailList.stream().map(RoleDetailDTO::getId).collect(Collectors.toList());
        }
        accountRoleQuery.setRoleIdList(roleIdList);
        List<AccountDetailDTO> accountRoleList = getAccountRoleDynamic(accountRoleQuery);
        //填充一些账号数据进入到角色分组list
        dealAccountGroupByRole(roleAccountDetailList, accountRoleList);
        return ResultJson.success(roleAccountDetailList);
    }


    public void dealAccountGroupByRole(List<RoleDetailDTO> roleDetailList, List<AccountDetailDTO> accountRoleList) {
        //处理账号以角色相关联数据分组 key为角色id value为相关账号
        Map<Integer, List<AccountDetailDTO>> accountGroupByRoleMap = new HashMap<>();
        for (AccountDetailDTO accountDetailDTO : accountRoleList) {
            Integer roleId = accountDetailDTO.getRoleId();
            List<AccountDetailDTO> accountDetailDTOS = accountGroupByRoleMap.get(roleId);
            if (CollectionUtils.isEmpty(accountDetailDTOS)) {
                List<AccountDetailDTO> saveAccountList = new ArrayList<>();
                saveAccountList.add(accountDetailDTO);
                accountGroupByRoleMap.put(roleId, saveAccountList);
            } else {
                accountDetailDTOS.add(accountDetailDTO);
            }
        }
        //填充账号数据
        for (RoleDetailDTO roleDetail : roleDetailList) {
            Integer roleId = roleDetail.getId();
            List<AccountDetailDTO> accounts = accountGroupByRoleMap.get(roleId);
            if (!CollectionUtils.isEmpty(accounts)) {
                roleDetail.setAccounts(accounts);
            }
        }
    }

    /**
     * 删除 账号内置角色/项目关系数据
     *
     * @param operateAccount
     * @param accountId
     * @param projectId
     * @param roleIds
     * @return
     */
    @Override
    public ResultJson deleteCommonInitializeRole(Account operateAccount, Integer accountId, Integer projectId, List<Integer> roleIds, Boolean deleteRole) {
        log.info("当前需要移除角色关联关系标识为={}", deleteRole);
        log.info("当前校验是否需要移除的项目id为={}", projectId);
        // 只有一个不能移除
        List<Integer> roleIdsDb = accountRoleService.findRoleIdByAccountId(accountId);
        if (CollectionUtils.isEmpty(roleIdsDb)) {
            return ResultJson.fail("该账号无任何角色关联数据,移除失败");
        }
        if (deleteRole) {
            if (1 == roleIdsDb.size()) {
                return ResultJson.fail("该用户只剩最后一个角色身份，无法移除");
            }
            //移除账号、角色关联关系
            QueryWrapper<AccountRole> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("account_id", accountId);
            queryWrapper.in("role_id", roleIds);
            accountRoleService.remove(queryWrapper);
            log.info("账号、角色关联关系移除成功，账号id={}，角色id={}", accountId, roleIds);
        }
        //检测当前项目id是否需要删除
        List<Integer> roleIdsNow = accountRoleService.findRoleIdByAccountId(accountId);
        if (!CollectionUtils.isEmpty(roleIdsNow)) {
            RoleQuery roleQuery = new RoleQuery();
            roleQuery.setIdList(roleIdsNow);
            List<Role> roleInfoList = roleService.getRoleList(null, roleQuery);
            Set<Integer> entIdSet = new HashSet<>();
            Set<Integer> proIdSet = new HashSet<>();
            for (Role r : roleInfoList) {
                if (null != r.getEnterpriseId()) {
                    entIdSet.add(r.getEnterpriseId());
                }
                if (null != r.getProjectId()) {
                    proIdSet.add(r.getProjectId());
                }
            }
            List<Integer> projectIdsDb = new ArrayList<>(proIdSet);
            //校验是否需要移除账号-项目 、账号-组织（项目级）数据  (项目id主导)
            removeAccountProject(accountId, projectId, projectIdsDb);
        }
        Account account = findById(accountId);
        //维护  账号、 业态角色 、 项目 之间的关系
        try {
            holdAccountInitRole(account, Arrays.asList(projectId), roleIds, OperationTypeEnum.DELETE.getType());
        } catch (Exception e) {
            log.info("维护账号业态角色与项目 之间的关系出现异常accountId={}，projectIds={}，roleIds={}", account.getId(), projectId.toString(), roleIds);
        }
        return ResultJson.success();
    }

    /**
     * 用于删除账号和项目关系时，需要检测出来当前角色的项目id对于这个账号在别的角色上是否存在使用关联，所以existRelationProIds 是当前账号所关联的项目id（通过角色反查）
     *
     * @param accountId
     * @param removeProjectId
     * @param existRelationProIds
     */
    public void removeAccountProject(Integer accountId, Integer removeProjectId, List<Integer> existRelationProIds) {
        log.info("现存账号角色反查出来关联关系的项目id={}", existRelationProIds.toString());
        log.info("计划需要移除的账号关联关系的项目id={}", removeProjectId);
        boolean needRemoveAccountProject = false;
        if (null != removeProjectId) {
            if (!CollectionUtils.isEmpty(existRelationProIds)) {
                if (!existRelationProIds.contains(removeProjectId)) {
                    needRemoveAccountProject = true;
                }
            } else {
                needRemoveAccountProject = true;
            }
        }
        log.info("校验移除项目id={}的结果为={}", removeProjectId, needRemoveAccountProject);
        if (needRemoveAccountProject) {
            //账号-项目关系需要删除
            QueryWrapper<AccountProject> accountProjectQueryWrapper = new QueryWrapper<>();
            accountProjectQueryWrapper.eq("account_id", accountId);
            accountProjectQueryWrapper.eq("project_id", removeProjectId);
            accountProjectService.remove(accountProjectQueryWrapper);
            Project project = projectService.findById(removeProjectId);
            //账号-组织 关系（项目层级需要删除）
            QueryWrapper<AccountOrganization> deleteWrapper = new QueryWrapper<>();
            deleteWrapper.eq("account_id", accountId);
            deleteWrapper.eq("organization_id", project.getOrganizationId());
            deleteWrapper.eq("enterprise_id", project.getEnterpriseId());
            accountOrganizationDao.delete(deleteWrapper);
        }
    }

    /**
     * 用于删除账号和企业关系时，需要检测出来当前角色的企业id对于这个账号在别的角色上是否存在使用关联，所以existRelationEntIds 是当前账号所关联的企业id（通过角色反查）
     *
     * @param accountId
     * @param removeRoleProId
     * @param removeRoleEntId
     * @param existRelationEntIds
     */
    public void removeAccountEnterprise(Integer accountId, Integer removeRoleProId, Integer removeRoleEntId, List<Integer> existRelationEntIds) {
        //校验是否需要移除账号-项目 、账号-组织（项目级）数据
        boolean needRemoveAccountEnterprise = false;
        if (null == removeRoleProId && null != removeRoleEntId) {
            if (!CollectionUtils.isEmpty(existRelationEntIds)) {
                if (!existRelationEntIds.contains(removeRoleEntId)) {
                    needRemoveAccountEnterprise = true;
                }
            } else {
                needRemoveAccountEnterprise = true;
            }
        }
        //校验是否需要移除账号-企业 、账号-组织（企业级）数据
        if (needRemoveAccountEnterprise) {
            OrganizationQuery organizationQuery = new OrganizationQuery();
            organizationQuery.withEnterpriseId(removeRoleEntId);
            organizationQuery.withTypes(Arrays.asList(OrganizationTypeEnum.ENTERPRISE.id.intValue()));
            Organization organization = organizationService.find(organizationQuery);
            //账号-组织 关系（企业层级需要删除）
            QueryWrapper<AccountOrganization> deleteWrapper = new QueryWrapper<>();
            deleteWrapper.eq("account_id", accountId);
            deleteWrapper.eq("organization_id", organization.getId());
            deleteWrapper.eq("enterprise_id", organization.getEnterpriseId());
            accountOrganizationDao.delete(deleteWrapper);
        } else {
            OrganizationQuery organizationQuery = new OrganizationQuery();
            organizationQuery.withEnterpriseId(removeRoleEntId);
            organizationQuery.withTypes(Arrays.asList(OrganizationTypeEnum.ENTERPRISE.id.intValue()));
            Organization organization = organizationService.find(organizationQuery);
            QueryWrapper<AccountOrganization> findWrapper = new QueryWrapper<>();
            findWrapper.eq("account_id", accountId);
            findWrapper.eq("organization_id", organization.getId());
            findWrapper.eq("enterprise_id", organization.getEnterpriseId());
            List<AccountOrganization> accountOrganizations = accountOrganizationDao.selectList(findWrapper);
            if (CollectionUtils.isEmpty(accountOrganizations)) {
                AccountOrganization accountOrganization = new AccountOrganization();
                accountOrganization.setAccountId(accountId);
                accountOrganization.setOrganizationId(organization.getId());
                accountOrganization.setEnterpriseId(organization.getEnterpriseId());
                accountOrganizationDao.insert(accountOrganization);
            }
        }
    }


    /**
     * 动态获取账号信息列表 分页
     * 与操作人相关
     *
     * @param page
     * @param accountQuery
     * @return
     */
    @Override
    public Page<Account> getAccountPageList(Account operateAccount, Page page, AccountQuery accountQuery) {
        if (null != accountQuery.getChineseOrderColumn()) {
            if (null == page.getOrders() || page.getOrders().isEmpty()) {
                List<OrderItem> order = new ArrayList<>(1);
                OrderItem item = new OrderItem();
                item.setColumn("CONVERT( " + accountQuery.getChineseOrderColumn() + " USING gbk ) COLLATE gbk_chinese_ci");
                order.add(item);
                page.setOrders(order);
            } else {
                List<OrderItem> order = page.getOrders();
                OrderItem item = new OrderItem();
                item.setColumn("CONVERT( " + accountQuery.getChineseOrderColumn() + " USING gbk ) COLLATE gbk_chinese_ci");
                order.add(item);
                page.setOrders(order);
            }
        }
        accountQuery = handleRequest(operateAccount, accountQuery);
        return accountDao.selectPage(page, handleParams(accountQuery));
    }

    /**
     * 动态获取账号列表 分页
     *
     * @param page
     * @param accountQuery
     * @return
     */
    @Override
    public Page<AccountDTO> getPageList(Page page, AccountQuery accountQuery) {
        accountQuery = handleRequest(null, accountQuery);
        if (Objects.nonNull(accountQuery.getReturnEmpty())) {
            if (accountQuery.getReturnEmpty()) {
                return page;
            }
        }
        Page<AccountDTO> accountPageList = accountDao.getPageListWithAuth(page, accountQuery);
        List<AccountDTO> accountRecords = accountPageList.getRecords();
        if (CollectionUtils.isEmpty(accountRecords)) {
            return accountPageList;
        }
        //填充账号列表返回的数据
        List<AccountDTO> accountDTOList = fillAccountData(accountQuery, accountRecords, true);
        Page<AccountDTO> resultPageList = new Page<>();
        resultPageList.setRecords(accountDTOList);
        resultPageList.setSize(accountPageList.getSize());
        resultPageList.setCurrent(accountPageList.getCurrent());
        resultPageList.setTotal(accountPageList.getTotal());
        return resultPageList;
    }

    /**
     * 获取账号列表 根据角色分组 (只根据普通内置角色&项目id)
     *
     * @param accountQuery
     * @return
     */
    @Override
    public List<RoleDetailVO> getAccountWithInitializeRoles(AccountQuery accountQuery) {
        Short industryId = accountQuery.getIndustryId();
        List<Integer> projectIdList = accountQuery.getProjectIdList();
        List<Integer> initializeRolesIds = accountQuery.getRoleIdList();
        List<RoleDetailVO> resultList = new ArrayList<>();
        List<Role> initializeRoles;
        //取出需要使用的角色（普通内置）
        if (CollectionUtils.isEmpty(initializeRolesIds)) {
            QueryWrapper<Role> initializeRoleQueryWrapper = new QueryWrapper<>();
            initializeRoleQueryWrapper.eq("type", RoleTypeEnum.COMMON.getCode());
            if (null != industryId) {
                initializeRoleQueryWrapper.in("industry_id", Arrays.asList(industryId));
            }
            initializeRoleQueryWrapper.eq("is_initialized", InitializeEnum.IS_INITIALIZE.getCode());
            initializeRoles = roleService.list(initializeRoleQueryWrapper);
            if (CollectionUtils.isEmpty(initializeRolesIds)) {
                return resultList;
            }
            initializeRolesIds = initializeRoles.stream().map(Role::getId).collect(Collectors.toList());
        } else {
            QueryWrapper<Role> initializeRoleQueryWrapper = new QueryWrapper<>();
            initializeRoleQueryWrapper.eq("type", RoleTypeEnum.COMMON.getCode());
            initializeRoleQueryWrapper.in("id", initializeRolesIds);
            initializeRoleQueryWrapper.eq("is_initialized", InitializeEnum.IS_INITIALIZE.getCode());
            initializeRoles = roleService.list(initializeRoleQueryWrapper);
            if (CollectionUtils.isEmpty(initializeRolesIds)) {
                return resultList;
            }
            initializeRolesIds = initializeRoles.stream().map(Role::getId).collect(Collectors.toList());
        }
        List<AccountDetailDTO> accountRoleList = getAccountRoleInfoByIdList(null, initializeRolesIds);
        List<Integer> accountIdsByProject = accountProjectService.list(null, projectIdList);
        List<AccountDetailDTO> usedForGroupByAccounts = new ArrayList<>();
        for (AccountDetailDTO accountDetailDTO : accountRoleList) {
            Integer accountId = accountDetailDTO.getAccountId();
            if (accountIdsByProject.contains(accountId)) {
                usedForGroupByAccounts.add(accountDetailDTO);
            }
        }
        //处理账号以角色相关联数据分组 key为角色id value为相关账号
        Map<Integer, List<AccountDetailDTO>> accountGroupByRoleMap = new HashMap<>();
        for (AccountDetailDTO accountDetailDTO : usedForGroupByAccounts) {
            Integer roleId = accountDetailDTO.getRoleId();
            List<AccountDetailDTO> accountDetailDTOS = accountGroupByRoleMap.get(roleId);
            if (CollectionUtils.isEmpty(accountDetailDTOS)) {
                List<AccountDetailDTO> saveAccountList = new ArrayList<>();
                saveAccountList.add(accountDetailDTO);
                accountGroupByRoleMap.put(roleId, saveAccountList);
            } else {
                accountDetailDTOS.add(accountDetailDTO);
            }
        }
        //填充账号数据
        for (Role role : initializeRoles) {
            Integer roleId = role.getId();
            List<AccountDetailDTO> accounts = accountGroupByRoleMap.get(roleId);
            RoleDetailVO roleDetailVO = new RoleDetailVO();
            BeanUtils.copyProperties(role, roleDetailVO);
            if (!CollectionUtils.isEmpty(accounts)) {
                roleDetailVO.setAccounts(accounts);
            }
            resultList.add(roleDetailVO);
        }
        return resultList;
    }

    /**
     * 编辑账号单表信息
     *
     * @param account
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultJson editAccountInfo(Account account) {
        if (Objects.isNull(account)) {
            log.error("账号信息account为空，无法修改");
            throw new DataException("账号信息不能为空");
        }
        if (Objects.isNull(account.getId())) {
            log.error("账号信息accountId为空，无法修改");
            throw new DataException("缺少账号信息");
        }
        if (StringUtils.isNotEmpty(account.getName())) {
            String nameCovert = EmojiParser.parseToAliases(account.getName());
            account.setName(nameCovert);
        }
        if (StringUtils.isNotEmpty(account.getNickname())) {
            // 检测用户昵称是否合格
            CompositeDetectionDTO compositeDetectionDTO = new CompositeDetectionDTO();
            compositeDetectionDTO.setTexts(Arrays.asList(account.getNickname().split(",")));
            Boolean detectionFlag = detectionService.detectionTextsAndImages(compositeDetectionDTO);
            if (!detectionFlag) {
                throw new DataException("昵称违规，无法修改");
            }
            String nickNameCovert = EmojiParser.parseToAliases(account.getNickname());
            account.setNickname(nickNameCovert);
        }
        if (StringUtils.isNotEmpty(account.getHeadImg())) {
            // 对APP头像进行图片检测
            CompositeDetectionDTO compositeDetectionDTO = new CompositeDetectionDTO();
            compositeDetectionDTO.setPics(Arrays.asList(account.getHeadImg().split(",")));
            Boolean isPass = detectionService.detectionTextsAndImages(compositeDetectionDTO);
            if (!isPass) {
                return ResultJson.fail("图片违规，上传失败");
            }
        }
        // 填充默认的开发者
        if (null == account.getDevelopId()) {
            account.setDevelopId(developerService.getDefault().getId());
        }
        //  业态下 账号唯一、手机号、邮箱 唯一验重
        accountUnique(account);
        UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", account.getId());
        if (StringUtils.isNotEmpty(account.getPassword())) {
            account.setPassword(encode(account));
        }
        int effectNumUpdate = accountDao.update(account, updateWrapper);
        if (effectNumUpdate != 1) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new DataException("更新账号数据失败");
        }
        Account accountDb = findById(account.getId());
        //edit account不发kafaka消息
        //updateSendToMQ(account, account.getPassword());
        //记录操作日志
        accountLogRecord(null, LogOperationTypeEnum.UPDATE, "编辑账号" + "【" + accountDb.getLoginName() + "】");
        return ResultJson.success("操作成功");
    }

    /**
     * 动态获取账号列表 不分页
     *
     * @param accountQuery
     * @return
     */
    @Override
    public List<AccountDTO> getList(AccountQuery accountQuery) {
        List<AccountDTO> accountRecords = new ArrayList<>();
        accountQuery = handleRequest(null, accountQuery);
        if (Objects.nonNull(accountQuery.getReturnEmpty())) {
            if (accountQuery.getReturnEmpty()) {
                return accountRecords;
            }
        }
        accountRecords = accountDao.getListWithAuth(accountQuery);
        if (CollectionUtils.isEmpty(accountRecords)) {
            return accountRecords;
        }
        //填充账号列表返回的数据
        List<AccountDTO> accountDTOList = fillAccountData(accountQuery, accountRecords, false);
        return accountDTOList;
    }

    @Override
    public Page<Account> getAccountsByPhones(Page page,List<String> phones) {
        if(CollectionUtils.isEmpty(phones)){
            return null;
        }
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_deleted",0);
        queryWrapper.in("phone",phones);
        Page<Account> result = accountDao.selectPage(page, queryWrapper);
        return result;
    }

    /**
     * 将查询处理的list，填充更多需要的数据
     *
     * @param accountQuery
     * @param accountRecords
     * @return
     */
    public List<AccountDTO> fillAccountData(AccountQuery accountQuery, List<AccountDTO> accountRecords, Boolean dataPermissionsCheck) {
        //转换账号-企业 信息map
        Map<Integer, Map<String, Object>> accountEnterpriseInfoMap = new HashMap<>();
        //转换账号-角色 信息map
        Map<Integer, Map<String, Object>> accountRoleInfoMap = new HashMap<>();
        //转换账号-项目 信息map
        Map<Integer, Map<String, Object>> accountProjectInfoMap = new HashMap<>();

        List<AccountDTO> accountDTOList = new ArrayList<>();
        Map<Integer, Boolean> updateCheckBatchMap = new HashMap<>();
        Map<Integer, Boolean> deleteCheckBatchMap = new HashMap<>();

        // 组织查询
        Map<Integer, List<Organization>> orgMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(accountRecords)) {
            List<Integer> accountIdList = accountRecords.stream().map(e -> e.getId()).collect(Collectors.toList());
            accountEnterpriseInfoMap = convertAccountEntMap(accountQuery, accountIdList);
            accountRoleInfoMap = convertAccountRoleMap(accountQuery, accountIdList, null);
            accountProjectInfoMap = convertAccountProMap(accountQuery, accountIdList);

            Short industryId = accountQuery.getIndustryId();
            RoleTypeEnum operateRoleType = accountQuery.getOperateRoleType();
            updateCheckBatchMap = updateAccountCheckBatch(industryId, operateRoleType, accountIdList);
            deleteCheckBatchMap = deleteAccountCheckBatch(industryId, operateRoleType, accountIdList);

            orgMap = getOrgMap(accountQuery, accountIdList);
        }

        //填充 角色名、企业名、项目名
        for (AccountDTO accountDTO : accountRecords) {
            Integer accountId = accountDTO.getId();
            if (StringUtils.isNotEmpty(accountDTO.getName())) {
                String name = accountDTO.getName();
                accountDTO.setName(EmojiParser.parseToUnicode(name));
            }
            if (StringUtils.isNotEmpty(accountDTO.getNickname())) {
                String name = accountDTO.getNickname();
                accountDTO.setNickname(EmojiParser.parseToUnicode(name));
            }
            //企业
            if (accountEnterpriseInfoMap.containsKey(accountDTO.getId())) {
                accountDTO.setEnterpriseIds((List<Integer>) accountEnterpriseInfoMap.get(accountDTO.getId()).get("entIds"));
                accountDTO.setEnterpriseName(accountEnterpriseInfoMap.get(accountDTO.getId()).get("entName").toString());
                accountDTO.setEnterpriseTypes((List<String>)accountEnterpriseInfoMap.get(accountDTO.getId()).get("entTypes"));
            } else {
                accountDTO.setEnterpriseName("");
            }
            //项目
            if (accountProjectInfoMap.containsKey(accountDTO.getId())) {
                List<Integer> proIds = (List<Integer>) accountProjectInfoMap.get(accountDTO.getId()).get("proIds");
                accountDTO.setProjectIds(proIds);
                accountDTO.setProjectCount(proIds.size());
                accountDTO.setProjectName(accountProjectInfoMap.get(accountDTO.getId()).get("proName").toString());
            } else {
                accountDTO.setProjectName("");
                accountDTO.setProjectCount(0);
            }
            //角色
            if (accountRoleInfoMap.containsKey(accountDTO.getId())) {
                Map<String, Object> roleInfoMap = accountRoleInfoMap.get(accountDTO.getId());
                List<Integer> roleIds = (List<Integer>) roleInfoMap.get("roleIds");
                accountDTO.setRoleIds(roleIds);
                accountDTO.setRoleCount(roleIds.size());
                accountDTO.setRoleName((String) roleInfoMap.get("roleName"));
                accountDTO.setRoleTopType((Integer) roleInfoMap.get("roleType"));
            } else {
                accountDTO.setRoleName("");
                accountDTO.setRoleCount(0);
            }
            //账号功能权限设置
            if (dataPermissionsCheck) {
                accountDTO.setCanUpdate(updateCheckBatchMap.get(accountId));
                accountDTO.setCanDelete(deleteCheckBatchMap.get(accountId));
            }
            accountDTO.setPassword(null);
            // 组织
            if (!CollectionUtils.isEmpty(orgMap.get(accountId))) {
                accountDTO.setOrganizations(orgMap.get(accountId).stream().filter(Objects::nonNull).collect(Collectors.toList()));
            } else {
                accountDTO.setOrganizations(Collections.emptyList());
            }
            accountDTOList.add(accountDTO);
        }
        return accountDTOList;
    }

    private Map<Integer, List<Organization>> getOrgMap(AccountQuery accountQuery, List<Integer> accountIdList) {
        Map<Integer, List<Organization>> result = new HashMap<>();
        QueryWrapper<AccountOrganization> accountOrganizationQueryWrapper = new QueryWrapper<>();
        accountOrganizationQueryWrapper.in("account_id", accountIdList);
        if(!CollectionUtils.isEmpty(accountQuery.getEnterpriseIdList())){
            accountOrganizationQueryWrapper.in("enterprise_id", accountQuery.getEnterpriseIdList());
        }
        List<AccountOrganization> accountOrganizations = accountOrganizationDao.selectList(accountOrganizationQueryWrapper);
        Map<Integer, List<Integer>> accountOrgIdMap = accountOrganizations.stream().collect(Collectors.groupingBy(AccountOrganization::getAccountId, Collectors.mapping(i -> i.getOrganizationId(), Collectors.toList())));
        List<Integer> orgIds = accountOrganizations.stream().map(i -> i.getOrganizationId()).distinct().collect(Collectors.toList());
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.select("id", "name");
        organizationQueryWrapper.in("id", orgIds);
        List<Organization> organizations = organizationService.list(organizationQueryWrapper);
        Map<Integer, Organization> orgMap = organizations.stream().collect(Collectors.toMap(Organization::getId, Function.identity()));
        for (Map.Entry<Integer, List<Integer>> entry : accountOrgIdMap.entrySet()) {
            List<Organization> orgs = entry.getValue().stream().map(i -> orgMap.get(i)).collect(Collectors.toList());
            result.put(entry.getKey(), orgs);
        }
        return result;
    }

    /**
     * 获取被放人身份列表
     *
     * @param industryId
     * @param accountSearch
     * @param account
     * @return
     */
    @Override
    public List<AccountDTO> getAccessedList(Short industryId, AccountSearchVO accountSearch, Account account) {
        AccountQuery accountQuery = convertDynamicAccountQuery(industryId, accountSearch, account);
        List<AccountDTO> accountList = accountService.getList(accountQuery);
        return accountList;
    }

    /**
     * 动态查询账号list Query条件填充
     *
     * @param industryId
     * @param accountSearch
     * @param operateAccount
     * @return
     */
    public AccountQuery convertDynamicAccountQuery(Short industryId, AccountSearchVO accountSearch, Account operateAccount) {
        boolean needAuth = true;
        if (Objects.nonNull(accountSearch.getNeedAuth())) {
            needAuth = accountSearch.getNeedAuth();
        }
        List<Integer> enterpriseIds = accountSearch.getEntIds();
        List<Integer> projectIds = accountSearch.getProIds();
        //获取当前登录操作账号的角色身份
        RoleTypeDTO accountRoleType = roleService.getAccountRoleType(operateAccount.getId());
        RoleTypeEnum operateRoleType = accountRoleType.getRoleTypeEnum();
        //默认根据企业首字母顺序排列
        //账号列表动态查询条件
        AccountQuery accountQuery = new AccountQuery();
        accountQuery.setIndustryId(industryId);
        accountQuery.setOperateRoleType(operateRoleType);
        accountQuery.setNeedProjectPerson(accountSearch.getNeedProjectPerson());
        //needAuth  与当前操作账号做权限交集
        if (needAuth) {
            //超管
            if (RoleTypeEnum.SUPPER_MANAGER.getCode() == operateRoleType.getCode()) {
                //额外查看超管账号
                fillSuperAdminIds(accountSearch, accountQuery);
                EnterpriseQuery enterpriseQuery = new EnterpriseQuery();
                enterpriseQuery.setIndustryIdList(Arrays.asList(industryId));
                List<Enterprise> enterprisesDb = enterpriseService.list(enterpriseQuery, null);
                //设置查询的企业ids
                if (!CollectionUtils.isEmpty(enterprisesDb)) {
                    List<Integer> enterpriseIdListDb = enterprisesDb.stream().map(Enterprise::getId).collect(Collectors.toList());
                    enterpriseIds = entIdsCrossDeal(enterpriseIds, enterpriseIdListDb);
                }
            } else if (RoleTypeEnum.ENT_MANAGER.getCode() == operateRoleType.getCode()) {
                //企管 只能查看自己企业id的账号
                List<Integer> enterpriseIdListDb = accountRoleType.getEnterpriseIdList();
                //设置查询的企业ids
                if (!CollectionUtils.isEmpty(enterpriseIdListDb)) {
                    enterpriseIds = entIdsCrossDeal(enterpriseIds, enterpriseIdListDb);
                }
            } else if (RoleTypeEnum.PRO_MANAGER.getCode() == operateRoleType.getCode()) {
                List<Integer> projectIdList = accountRoleType.getProjectIdList();
                //将项目所属的企业获取出来
                ProjectQuery projectQuery = new ProjectQuery();
                projectQuery.withIdList(projectIdList);
                List<Project> projects = projectService.list(projectQuery, null);
                if (!CollectionUtils.isEmpty(projects)) {
                    //设置查询的项目ids
                    List<Integer> projectIdListDb = projects.stream().map(Project::getId).collect(Collectors.toList());
                    projectIds = proIdsCrossDeal(projectIds, projectIdListDb);
                    //设置查询的企业ids
                    List<Integer> enterpriseIdListDb = projects.stream().map(Project::getEnterpriseId).collect(Collectors.toList());
                    enterpriseIds = entIdsCrossDeal(enterpriseIds, enterpriseIdListDb);
                }
                //设置项目管理员可查看的账号id
                List<Integer> accountIdList = proAdminCanSearchSetting(operateAccount);
                accountQuery.setIdList(accountIdList);
            }
        }
        if (!CollectionUtils.isEmpty(enterpriseIds)) {
            accountQuery.setEnterpriseIdList(enterpriseIds);
        }
        if (!CollectionUtils.isEmpty(projectIds)) {
            accountQuery.setProjectIdList(projectIds);
        }
        accountQuery.setOrganizationIds(accountSearch.getOrganizationIds());
        accountQuery.setCurrentOrganization(accountSearch.isCurrentOrganization());
        searchSetting(accountSearch, accountQuery);
        //如果不包含游客角色类型
        if (!accountSearch.getNeedIncludeTourist()) {
            List<Role> touristRoleByIndustryId = roleService.getTouristRoleByIndustryId(industryId);
            if (!CollectionUtils.isEmpty(touristRoleByIndustryId)) {
                List<Integer> collect = touristRoleByIndustryId.stream().map(role -> role.getId()).collect(Collectors.toList());
                List<Integer> excludeRoleIdList = accountQuery.getExcludeRoleIdList();
                if (excludeRoleIdList == null) {
                    excludeRoleIdList = new ArrayList<>();
                }
                excludeRoleIdList.addAll(collect);
                accountQuery.setExcludeRoleIdList(excludeRoleIdList);
            }
        }
        return accountQuery;
    }

    /**
     * 搜索条件设置
     *
     * @param accountSearch
     * @param accountQuery
     */
    public void searchSetting(AccountSearchVO accountSearch, AccountQuery accountQuery) {
        if (!CollectionUtils.isEmpty(accountSearch.getRoleIds())) {
            accountQuery.setRoleIdList(accountSearch.getRoleIds());
        }
        if (StringUtils.isNotEmpty(accountSearch.getLikeSearch())) {
            accountQuery.setLikeSearch(accountSearch.getLikeSearch());
        }
        if (StringUtils.isNotEmpty(accountSearch.getLikeNameOrPhone())) {
            accountQuery.setLikeNameOrPhone(accountSearch.getLikeNameOrPhone());
        }
        if (StringUtils.isNotEmpty(accountSearch.getLikeRoleName())) {
            accountQuery.setLikeRoleName(accountSearch.getLikeRoleName());
        }
        if (StringUtils.isNotEmpty(accountSearch.getLikeLoginName())) {
            accountQuery.setLikeLoginName(accountSearch.getLikeLoginName());
        }
        if (StringUtils.isNotEmpty(accountSearch.getLikeName())) {
            accountQuery.setLikeName(accountSearch.getLikeName());
        }
        if (!CollectionUtils.isEmpty(accountSearch.getAccountIds())) {
            accountQuery.setIdList(accountSearch.getAccountIds());
        }
        if (null != accountSearch.getNeedCommonInitialized()) {
            accountQuery.setNeedCommonInitialized(accountSearch.getNeedCommonInitialized());
        }
        if (null != accountSearch.getName() && accountSearch.getName().trim().length() != 0) {
            accountQuery.setName(accountSearch.getName());
        }
    }


    /**
     * 项目管理员功能权限过滤 （只能查看项管和普通账号）
     *
     * @param operateAccount
     * @return
     */
    public List<Integer> proAdminCanSearchSetting(Account operateAccount) {
        List<Role> roleList = roleService.getRoleList(operateAccount, null);
        List<Integer> roleIdList = roleList.stream().map(Role::getId).collect(Collectors.toList());
        List<Integer> accountIdList = accountRoleService.findByRoleId(roleIdList);
        Set<Integer> accountIdSet = new HashSet<>(accountIdList);
        accountIdList = new ArrayList<>(accountIdSet);
        //去除超管 、去除企管
        accountIdList = removeSuperAdminAccount(accountIdList);
        accountIdList = removeEntAdminAccount(accountIdList);
        return accountIdList;
    }

    /**
     * 移除企管账号
     *
     * @param accountIdList
     * @return
     */
    public List<Integer> removeEntAdminAccount(List<Integer> accountIdList) {
        List<Integer> accountIds = accountService.getAdminAccountDynamic(RoleTypeEnum.MANAGER.getCode(), BusinessType.ENTERPRISE.getCode(), accountIdList);
        List<Integer> resultList = new ArrayList<>();
        if (CollectionUtils.isEmpty(accountIds)) {
            resultList.addAll(accountIdList);
        } else {
            for (Integer id : accountIdList) {
                if (!accountIds.contains(id)) {
                    resultList.add(id);
                }
            }
        }
        return resultList;
    }

    /**
     * 移除超管账号
     *
     * @param accountIdList
     * @return
     */
    public List<Integer> removeSuperAdminAccount(List<Integer> accountIdList) {
        List<Integer> accountIds = accountService.getAdminAccountDynamic(RoleTypeEnum.SUPPER_MANAGER.getCode(), BusinessType.INDUSTRY.getCode(), accountIdList);
        List<Integer> resultList = new ArrayList<>();
        if (CollectionUtils.isEmpty(accountIds)) {
            resultList.addAll(accountIdList);
        } else {
            for (Integer id : accountIdList) {
                if (!accountIds.contains(id)) {
                    resultList.add(id);
                }
            }
        }
        return resultList;
    }

    /**
     * 项目id取交集
     *
     * @param projectIds
     * @param projectIdListDb
     * @return
     */
    public List<Integer> proIdsCrossDeal(List<Integer> projectIds, List<Integer> projectIdListDb) {
        if (!CollectionUtils.isEmpty(projectIdListDb)) {
            //企业id 与 传入的企业id取交集
            if (!CollectionUtils.isEmpty(projectIds)) {
                List<Integer> entIdsResult = projectIdListDb.stream().filter(projectIds::contains).collect(Collectors.toList());
                projectIds = entIdsResult;
            } else {
                projectIds = new ArrayList<>(projectIdListDb);
            }
        }
        return projectIds;
    }

    /**
     * 填充超管账号（超管能查看超管）
     *
     * @param accountSearch
     * @param accountQuery
     */
    public void fillSuperAdminIds(AccountSearchVO accountSearch, AccountQuery accountQuery) {
        RoleQuery roleQuery = new RoleQuery();
        roleQuery.setIndustryIdList(Arrays.asList(accountQuery.getIndustryId()));
        roleQuery.setGrade(BusinessType.INDUSTRY.getCode());
        roleQuery.setType(RoleTypeEnum.SUPPER_MANAGER.getCode());
        List<Role> superManagerRoleList = roleService.getRoleList(null, roleQuery);
        if (!CollectionUtils.isEmpty(superManagerRoleList)) {
            List<Integer> superManagerRoleIds = superManagerRoleList.stream().map(Role::getId).collect(Collectors.toList());
            List<Integer> superManagerAccountIds = accountRoleService.findByRoleId(superManagerRoleIds);
            //如果不根据企业、项目筛选，需要额外查询出超管账号
            if (CollectionUtils.isEmpty(accountSearch.getEntIds()) && CollectionUtils.isEmpty(accountSearch.getProIds())) {
                accountQuery.setOrSuperManagerIds(superManagerAccountIds);
            }
        }
    }

    /**
     * 企业id取交集
     *
     * @param enterpriseIds
     * @param enterpriseIdListDb
     * @return
     */
    public List<Integer> entIdsCrossDeal(List<Integer> enterpriseIds, List<Integer> enterpriseIdListDb) {
        if (!CollectionUtils.isEmpty(enterpriseIdListDb)) {
            //企业id 与 传入的企业id取交集
            if (!CollectionUtils.isEmpty(enterpriseIds)) {
                List<Integer> entIdsResult = enterpriseIdListDb.stream().filter(enterpriseIds::contains).collect(Collectors.toList());
                enterpriseIds = entIdsResult;
            } else {
                enterpriseIds = new ArrayList<>(enterpriseIdListDb);
            }
        }
        return enterpriseIds;
    }

    /**
     * 修改账号 权限范围检测 （批量）
     *
     * @param industryId
     * @param operateRoleType
     * @param accountIdList
     * @return
     */
    public Map<Integer, Boolean> updateAccountCheckBatch(Short industryId, RoleTypeEnum operateRoleType, List<Integer> accountIdList) {
        Map<Integer, Boolean> updateCheckResultMap = new HashMap<>();
        Map<Integer, RoleTypeDTO> accountRoleTypeMap = roleService.getAccountRoleTypeBatch(accountIdList);
        for (Integer accountId : accountRoleTypeMap.keySet()) {
            RoleTypeDTO roleTypeDTO = accountRoleTypeMap.get(accountId);
            RoleTypeEnum updateAccountRoleType = roleTypeDTO.getRoleTypeEnum();
            // 账号修改 权限验证
            if (!(RoleTypeEnum.SUPPER_MANAGER.equals(operateRoleType)
                    || RoleTypeEnum.OPERATE_MANAGER.equals(operateRoleType)
                    || RoleTypeEnum.ENT_MANAGER.equals(operateRoleType)
                    || RoleTypeEnum.PRO_MANAGER.equals(operateRoleType)
                    || RoleTypeEnum.COMMON.equals(operateRoleType))) {
                // log.warn("当前操作员无角色账号管理权限");
                updateCheckResultMap.put(accountId, false);
                continue;
            }
            //业态后台 任何角色都不允许修改超级管理员角色
            if (RoleTypeEnum.SUPPER_MANAGER.equals(updateAccountRoleType)) {
                //不能修改超级管理员角色账号
                updateCheckResultMap.put(accountId, false);
                continue;
            }
            //运维管理角色 无法修改 运维管理角色
            if (RoleTypeEnum.OPERATE_MANAGER.equals(operateRoleType)) {
                if (RoleTypeEnum.OPERATE_MANAGER.equals(updateAccountRoleType)) {
                    //运维角色不能修改运维角色账号
                    updateCheckResultMap.put(accountId, false);
                    continue;
                }
            }
            //企业管理员 无法修改 运维角色、企业管理员
//            if (RoleTypeEnum.ENT_MANAGER.equals(operateRoleType)) {
//                if (RoleTypeEnum.OPERATE_MANAGER.equals(updateAccountRoleType)
//                        || RoleTypeEnum.ENT_MANAGER.equals(updateAccountRoleType)) {
//                    //企业管理员不能修改运维角色账号/企业管理员角色账号
//                    updateCheckResultMap.put(accountId, false);
//                    continue;
//                }
//            }
            //项目管理员 无法修改 项目管理员
            if (RoleTypeEnum.PRO_MANAGER.equals(operateRoleType) || RoleTypeEnum.COMMON.equals(operateRoleType)) {
                if (RoleTypeEnum.SUPPER_MANAGER.equals(updateAccountRoleType)
                        || RoleTypeEnum.OPERATE_MANAGER.equals(updateAccountRoleType)
                        || RoleTypeEnum.ENT_MANAGER.equals(updateAccountRoleType)
                        || RoleTypeEnum.PRO_MANAGER.equals(updateAccountRoleType)) {
                    //项目管理员不能修改运维角色账号\企业角色管理员账号\项目管理员角色账号
                    updateCheckResultMap.put(accountId, false);
                    continue;
                }
            }
            //校验规则都通过，那么就是可以修改
            updateCheckResultMap.put(accountId, true);
        }
        return updateCheckResultMap;
    }

    /**
     * 删除账号 权限范围检测 （批量）
     *
     * @param industryId
     * @param operateRoleType
     * @param accountIdList
     * @return
     */
    public Map<Integer, Boolean> deleteAccountCheckBatch(Short industryId, RoleTypeEnum operateRoleType, List<Integer> accountIdList,Integer enterpriseId) {
        Map<Integer, Boolean> deleteCheckResultMap = new HashMap<>();
        Map<Integer, RoleTypeDTO> accountRoleTypeMap = roleService.getAccountRoleTypeBatch(accountIdList);
        for (Integer accountId : accountRoleTypeMap.keySet()) {
            RoleTypeDTO roleTypeDTO = accountRoleTypeMap.get(accountId);
            RoleTypeEnum deleteAccountRoleType = roleTypeDTO.getRoleTypeEnum();
            // 账号修改 权限验证
            if (!(RoleTypeEnum.SUPPER_MANAGER.equals(operateRoleType)
                    || RoleTypeEnum.OPERATE_MANAGER.equals(operateRoleType)
                    || RoleTypeEnum.ENT_MANAGER.equals(operateRoleType)
                    || RoleTypeEnum.PRO_MANAGER.equals(operateRoleType)
                    || RoleTypeEnum.COMMON.equals(operateRoleType))) {
                //log.warn("当前操作员无角色账号管理权限");
                deleteCheckResultMap.put(accountId, false);
                continue;
            }
            //业态后台 任何角色都不允许修改超级管理员角色
            if (RoleTypeEnum.SUPPER_MANAGER.equals(deleteAccountRoleType)) {
                deleteCheckResultMap.put(accountId, false);
                continue;
            }
            //运维管理角色 无法修改 运维管理角色
            if (RoleTypeEnum.OPERATE_MANAGER.equals(operateRoleType)) {
                if (RoleTypeEnum.OPERATE_MANAGER.equals(deleteAccountRoleType)) {
                    //运维角色不能修改运维角色账号
                    deleteCheckResultMap.put(accountId, false);
                    continue;
                }
            }
            //企业管理员 无法修改 运维角色、企业管理员
            if (RoleTypeEnum.ENT_MANAGER.equals(operateRoleType)) {
                if (RoleTypeEnum.OPERATE_MANAGER.equals(deleteAccountRoleType)
                        || RoleTypeEnum.ENT_MANAGER.equals(deleteAccountRoleType)) {
                    //企业管理员不能修改运维角色账号/企业管理员角色账号
                    deleteCheckResultMap.put(accountId, false);
                    continue;
                }
            }
            //项目管理员 无法修改 项目管理员
            if (RoleTypeEnum.PRO_MANAGER.equals(operateRoleType) || RoleTypeEnum.COMMON.equals(operateRoleType)) {
                if (RoleTypeEnum.SUPPER_MANAGER.equals(deleteAccountRoleType)
                        || RoleTypeEnum.OPERATE_MANAGER.equals(deleteAccountRoleType)
                        || RoleTypeEnum.ENT_MANAGER.equals(deleteAccountRoleType)
                        || RoleTypeEnum.PRO_MANAGER.equals(deleteAccountRoleType)) {
                    //项目管理员不能修改运维角色账号\企业角色管理员账号\项目管理员角色账号
                    deleteCheckResultMap.put(accountId, false);
                    continue;
                }
            }
            //校验规则都通过，那么就是可以修改
            deleteCheckResultMap.put(accountId, true);
        }
        return deleteCheckResultMap;
    }
    /**
     * 修改账号 权限范围检测 （单个）
     *
     * @param industryId
     * @param operateRoleType
     * @param updateAccountRoleType
     * @return
     */
    @Override
    public Boolean updateAccountCheck(Short industryId, RoleTypeEnum operateRoleType, RoleTypeEnum updateAccountRoleType) {
        // 账号修改 权限验证 只有管理角色才能更新
//        if (!(RoleTypeEnum.SUPPER_MANAGER.equals(operateRoleType)
//                || RoleTypeEnum.OPERATE_MANAGER.equals(operateRoleType)
//                || RoleTypeEnum.ENT_MANAGER.equals(operateRoleType)
//                || RoleTypeEnum.PRO_MANAGER.equals(operateRoleType))) {
//            // log.warn("当前操作员无角色账号管理权限");
//            return false;
//        }
        //业态后台 任何角色都不允许修改超级管理员角色
        if (RoleTypeEnum.SUPPER_MANAGER.equals(updateAccountRoleType)) {
            //不能修改超级管理员角色账号
            return false;
        }
        //运维管理角色 无法修改 运维管理角色
        if (RoleTypeEnum.OPERATE_MANAGER.equals(operateRoleType)) {
            if (RoleTypeEnum.OPERATE_MANAGER.equals(updateAccountRoleType)) {
                //运维角色不能修改运维角色账号
                return false;
            }
        }
        //企业管理员 无法修改 运维角色、企业管理员
        if (RoleTypeEnum.ENT_MANAGER.equals(operateRoleType)) {
            if (RoleTypeEnum.OPERATE_MANAGER.equals(updateAccountRoleType)
                    || RoleTypeEnum.ENT_MANAGER.equals(updateAccountRoleType)) {
                //企业管理员不能修改运维角色账号/企业管理员角色账号
                return false;
            }
        }
        //项目管理员 无法修改 项目管理员
        if (RoleTypeEnum.PRO_MANAGER.equals(operateRoleType)) {
            if (RoleTypeEnum.OPERATE_MANAGER.equals(updateAccountRoleType)
                    || RoleTypeEnum.ENT_MANAGER.equals(updateAccountRoleType)
                    || RoleTypeEnum.PRO_MANAGER.equals(updateAccountRoleType)) {
                //项目管理员不能修改运维角色账号\企业角色管理员账号\项目管理员角色账号
                return false;
            }

        }
        return true;
    }


    /**
     * 删除账号 权限范围检测 （批量）
     *
     * @param industryId
     * @param operateRoleType
     * @param accountIdList
     * @return
     */
    public Map<Integer, Boolean> deleteAccountCheckBatch(Short industryId, RoleTypeEnum operateRoleType, List<Integer> accountIdList) {
        Map<Integer, Boolean> deleteCheckResultMap = new HashMap<>();
        Map<Integer, RoleTypeDTO> accountRoleTypeMap = roleService.getAccountRoleTypeBatch(accountIdList);
        for (Integer accountId : accountRoleTypeMap.keySet()) {
            RoleTypeDTO roleTypeDTO = accountRoleTypeMap.get(accountId);
            RoleTypeEnum deleteAccountRoleType = roleTypeDTO.getRoleTypeEnum();
            // 账号修改 权限验证
            if (!(RoleTypeEnum.SUPPER_MANAGER.equals(operateRoleType)
                    || RoleTypeEnum.OPERATE_MANAGER.equals(operateRoleType)
                    || RoleTypeEnum.ENT_MANAGER.equals(operateRoleType)
                    || RoleTypeEnum.PRO_MANAGER.equals(operateRoleType)
                    || RoleTypeEnum.COMMON.equals(operateRoleType))) {
                //log.warn("当前操作员无角色账号管理权限");
                deleteCheckResultMap.put(accountId, false);
                continue;
            }
            //业态后台 任何角色都不允许修改超级管理员角色
            if (RoleTypeEnum.SUPPER_MANAGER.equals(deleteAccountRoleType)) {
                deleteCheckResultMap.put(accountId, false);
                continue;
            }
            //运维管理角色 无法修改 运维管理角色
            if (RoleTypeEnum.OPERATE_MANAGER.equals(operateRoleType)) {
                if (RoleTypeEnum.OPERATE_MANAGER.equals(deleteAccountRoleType)) {
                    //运维角色不能修改运维角色账号
                    deleteCheckResultMap.put(accountId, false);
                    continue;
                }
            }
            //企业管理员 无法修改 运维角色、企业管理员
            if (RoleTypeEnum.ENT_MANAGER.equals(operateRoleType)) {
                if (RoleTypeEnum.OPERATE_MANAGER.equals(deleteAccountRoleType)
                        || RoleTypeEnum.ENT_MANAGER.equals(deleteAccountRoleType)) {
                    //企业管理员不能修改运维角色账号/企业管理员角色账号
                    deleteCheckResultMap.put(accountId, false);
                    continue;
                }
            }
            //项目管理员 无法修改 项目管理员
            if (RoleTypeEnum.PRO_MANAGER.equals(operateRoleType) || RoleTypeEnum.COMMON.equals(operateRoleType)) {
                if (RoleTypeEnum.SUPPER_MANAGER.equals(deleteAccountRoleType)
                        || RoleTypeEnum.OPERATE_MANAGER.equals(deleteAccountRoleType)
                        || RoleTypeEnum.ENT_MANAGER.equals(deleteAccountRoleType)
                        || RoleTypeEnum.PRO_MANAGER.equals(deleteAccountRoleType)) {
                    //项目管理员不能修改运维角色账号\企业角色管理员账号\项目管理员角色账号
                    deleteCheckResultMap.put(accountId, false);
                    continue;
                }
            }
            //校验规则都通过，那么就是可以修改
            deleteCheckResultMap.put(accountId, true);
        }
        return deleteCheckResultMap;
    }

    @Override
    public Map<Integer, List<Account>> findBySpace(OrganizationQuery organizationQuery) {
        if (CollectionUtils.isEmpty(organizationQuery.getIds())) {
            return Collections.emptyMap();
        }
        QueryWrapper<AccountOrganization> accountOrganizationQueryWrapper = new QueryWrapper<>();
        accountOrganizationQueryWrapper.select("account_id, organization_id");
        organizationQueryHandler(organizationQuery, accountOrganizationQueryWrapper);
        List<AccountOrganization> accountOrganizations = accountOrganizationDao.selectList(accountOrganizationQueryWrapper);
        if (CollectionUtils.isEmpty(accountOrganizations)) {
            return Collections.emptyMap();
        }
        List<Integer> collect = accountOrganizations.stream().map(i -> i.getAccountId()).distinct().collect(Collectors.toList());
        List<Account> accounts = this.listByIds(collect);
        List<Account> collect3 = accounts.stream().map(i -> i.setPassword("-")).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(accounts)) {
            log.warn("数据错误， 账号不存在。 {}", organizationQuery);
            return Collections.emptyMap();
        }
        Map<Integer, Account> collect1 = collect3.stream().collect(Collectors.toMap(Account::getId, Function.identity()));
        Map<Integer, List<Account>> collect2 = accountOrganizations.stream().collect(Collectors.groupingBy(AccountOrganization::getOrganizationId, Collectors.mapping(i -> collect1.get(i.getAccountId()), Collectors.toList())));
        return collect2;
    }

    @Override
    public ResultJson updateAccountAdminV2(AbstractAccount operator, Account account, AccountRelation accountRelation, List<PermissionGroupDTO> asList) {
        updateById(account);
        accountRelationUpdate(account.getId(), null == accountRelation ? null : accountRelation.getEnterpriseIds(),
                null == accountRelation ? null : accountRelation.getProjectIds(),
                null == accountRelation ? null : accountRelation.getRoleIds());
        savePermissionGroup(account.getId(), asList);
        return ResultJson.success();
    }

    @Override
    public ResultJson updateAccount(AbstractAccount operator, Account account) {
        accountDao.updateById(account);
        return ResultJson.success();
    }

    @Override
    public ResultJson setLoginTime(Integer id) {
        Account account = accountDao.selectById(id);
        if (null == account) {
            return ResultJson.fail("账号不存在");
        }
        account.setLoginTime(new Date());
        accountDao.updateById(account);
        return ResultJson.success();
    }

    @Override
    public Map<Integer, List<Account>> getByRoleIds(List<Integer> collect) {
        if (CollectionUtils.isEmpty(collect)) {
            return Collections.emptyMap();
        }
        QueryWrapper<AccountRole> accountRoleQueryWrapper = new QueryWrapper<>();
        accountRoleQueryWrapper.in("role_id", collect);
        List<AccountRole> list = accountRoleService.list(accountRoleQueryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            return Collections.emptyMap();
        }
        List<Integer> accountIds = list.stream().map(i -> i.getAccountId()).collect(Collectors.toList());
        Map<Integer, List<Integer>> roleAccountIdMap = list.stream().collect(Collectors.groupingBy(AccountRole::getRoleId, Collectors.mapping(AccountRole::getAccountId, Collectors.toList())));

        //  查询帐号信息 不需要根据条件查询帐号信息，直接用id就行，帐号删除的时候也会删除角色关联关系，删除的帐号不会出现在这里
        List<Account> accounts = accountDao.selectBatchIds(accountIds);
        Map<Integer, Account> accountMap = accounts.stream().map(i -> i.setPassword("-")).collect(Collectors.toMap(Account::getId, Function.identity()));
        Map<Integer, List<Account>> resultMap = new HashMap<>(roleAccountIdMap.size());

        for (Map.Entry<Integer, List<Integer>> integerListEntry : roleAccountIdMap.entrySet()) {
            List<Integer> value = integerListEntry.getValue();
            List<Account> accounts1 = value.stream().filter(j -> null != accountMap.get(j)).map(i -> accountMap.get(i)).collect(Collectors.toList());
            resultMap.put(integerListEntry.getKey(), accounts1);
        }
        return resultMap;
    }

    private void organizationQueryHandler(OrganizationQuery organizationQuery, QueryWrapper<AccountOrganization> queryWrapper) {

        if (null == organizationQuery) {
            queryWrapper.eq("id", -1);
            return;
        }
        if (!CollectionUtils.isEmpty(organizationQuery.ids)) {
            queryWrapper.in("organization_id", organizationQuery.ids);
        }
        if (!CollectionUtils.isEmpty(organizationQuery.types)) {
            queryWrapper.in("type", organizationQuery.types);
        }
        if (!CollectionUtils.isEmpty(organizationQuery.enterpriseIds)) {
            queryWrapper.in("enterprise_id", organizationQuery.enterpriseIds);
        }
    }


    /**
     * 是否是非当前企业企管的普通用户
     * @param accountOperatorAuth
     * @return
     */
    private boolean containEnterpriseManager(AccountOperatorAuth accountOperatorAuth){
        if(null == accountOperatorAuth || null == accountOperatorAuth.getCurrentEnterpriseId()){
            return true;
        }
        // 当账号的企业+角色满足：企业+当前企业的管理员时，该账号在【角色权限】不可被操作； 708206232
        QueryWrapper<AccountRole> accountRoleQueryWrapper = new QueryWrapper<>();
        accountRoleQueryWrapper.select("role_id");
        accountRoleQueryWrapper.eq("account_id", accountOperatorAuth.getModifiedAccount().getId());
        List<AccountRole> list = accountRoleService.list(accountRoleQueryWrapper);
        if(!CollectionUtils.isEmpty(list)){
            QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();

            roleQueryWrapper.eq("type", RoleTypeEnum.MANAGER.code);
            roleQueryWrapper.eq("is_deleted", false);
            roleQueryWrapper.eq("enterprise_id", accountOperatorAuth.getCurrentEnterpriseId());
            roleQueryWrapper.in("id", list.stream().map(i -> i.getRoleId()).collect(Collectors.toList()));
            List<Role> list1 = roleService.list(roleQueryWrapper);
            return CollectionUtils.isEmpty(list1);
        }else{
            return true;
        }
    }

    /**
     * 删除账号 权限范围检测 （单个）
     *
     * @param industryId
     * @param operateRoleType
     * @param updateAccountRoleType
     * @return
     */
    @Override
    public Boolean deleteAccountCheck(Short industryId, RoleTypeEnum operateRoleType, RoleTypeEnum updateAccountRoleType, AccountOperatorAuth accountOperatorAuth) {
        // 账号修改 权限验证
//        if (!(RoleTypeEnum.SUPPER_MANAGER.equals(operateRoleType)
//                || RoleTypeEnum.OPERATE_MANAGER.equals(operateRoleType)
//                || RoleTypeEnum.ENT_MANAGER.equals(operateRoleType)
//                || RoleTypeEnum.PRO_MANAGER.equals(operateRoleType)
//                || RoleTypeEnum.COMMON.equals(operateRoleType))) {
//            //log.warn("当前操作员无角色账号管理权限");
//            return false;
//        }
        //业态后台 任何角色都不允许修改超级管理员角色
        if (RoleTypeEnum.SUPPER_MANAGER.equals(updateAccountRoleType)) {
            //超级管理员角色账号不能删除
            return false;
        }
        //运维管理角色
        if (RoleTypeEnum.OPERATE_MANAGER.equals(operateRoleType)) {
            if (RoleTypeEnum.OPERATE_MANAGER.equals(updateAccountRoleType)) {
                //运维角色不能删除运维角色账号
                return false;
            }
        }
        //企业管理员
//        if (RoleTypeEnum.ENT_MANAGER.equals(operateRoleType)) {
//            if (RoleTypeEnum.OPERATE_MANAGER.equals(updateAccountRoleType)
//                    || RoleTypeEnum.ENT_MANAGER.equals(updateAccountRoleType)) {
//                //企业管理员不能删除运维角色账号/企业角色账号
//                return false;
//            }
//        }
        //项目管理员
        if (RoleTypeEnum.PRO_MANAGER.equals(operateRoleType) || RoleTypeEnum.COMMON.equals(operateRoleType)) {
            if (RoleTypeEnum.OPERATE_MANAGER.equals(updateAccountRoleType)
                    || RoleTypeEnum.ENT_MANAGER.equals(updateAccountRoleType)
                    || RoleTypeEnum.PRO_MANAGER.equals(updateAccountRoleType)) {
                //项目管理员不能删除运维角色账号/企业角色账号/项目角色账号
                return false;
            }
        }

        return containEnterpriseManager(accountOperatorAuth);
    }


    /**
     * 该账号是否允许被当前操作账号 修改 / 删除
     *
     * @param operateRoleType
     * @param updateAccountRoleType
     * @return
     */
    public Map<String, Boolean> canUpdateOrDelete(Short industryId, RoleTypeEnum operateRoleType, RoleTypeEnum updateAccountRoleType) {
        Map<String, Boolean> map = new HashMap<>(2);
        Boolean checkUpdateResult = updateAccountCheck(industryId, operateRoleType, updateAccountRoleType);
        map.put("canUpdate", checkUpdateResult);
        Boolean checkDeleteResult = deleteAccountCheck(industryId, operateRoleType, updateAccountRoleType, null);
        map.put("canDelete", checkDeleteResult);
        return map;
    }


    /**
     * 动态获取某个账号
     *
     * @param operateAccount
     * @param accountQuery
     * @return
     */
    @Override
    public Account getAccount(Account operateAccount, AccountQuery accountQuery) {
        // 处理权限信息
        accountQuery = handleRequest(operateAccount, accountQuery);
        return accountDao.selectOne(handleParams(accountQuery));
    }

    /**
     * 根据企业id 查找出关联账号的信息以及企业信息
     *
     * @param enterpriseIdList
     * @return
     */
    @Override
    public List<AccountDetailDTO> getAccountEnterpriseInfoByIdList(List<Integer> enterpriseIdList, List<Integer> accountIdList) {
        return accountDao.getAccountEnterpriseInfoByIdList(enterpriseIdList, accountIdList);
    }

    @Override
    public Map<Integer,List<Enterprise>> findEnterpriseMap(List<Integer> accountIds) {
        if (accountIds.isEmpty()){
            log.error("参数错误");
        }
        QueryWrapper<StaffOrganization> staffOrganizationQueryWrapper = new QueryWrapper<>();
        staffOrganizationQueryWrapper.in("account_id", accountIds);
        List<StaffOrganization> staffOrganizations = staffOrganizationService.list(staffOrganizationQueryWrapper);
        if (staffOrganizations.isEmpty()){
            log.warn("数据错误，查询不到员工组织信息");
            return Collections.emptyMap();
        }
        List<Integer> enterpriseIds = staffOrganizations.stream().map(StaffOrganization::getEnterpriseId).distinct().collect(Collectors.toList());

        Map<Integer,List<Integer>> staffIdMap = staffOrganizations.stream().collect((Collectors.groupingBy(StaffOrganization::getAccountId,Collectors.mapping(StaffOrganization::getEnterpriseId, Collectors.toList()))));

        List<Enterprise> enterprises = enterpriseService.listByIds(enterpriseIds);
        if (enterprises.isEmpty()){
            log.warn("数据错误，查询不到企业信息");
            return Collections.emptyMap();
        }

        Map<Integer,List<Enterprise>> result = new HashMap<>();

        for (Map.Entry<Integer, List<Integer>> integerListEntry : staffIdMap.entrySet()){
            List<Enterprise> enterpriseList = enterprises.stream().filter(i -> integerListEntry.getValue().contains(i.getId())).collect(Collectors.toList());
            result.put(integerListEntry.getKey(),enterpriseList);
        }
        return result;
    }

    /**
     * 单表动态查询-不分页
     *
     * @param accountQuery
     * @return
     */
    @Override
    public List<Account> getAccountList(Account operateAccount, AccountQuery accountQuery) {
        accountQuery = handleRequest(operateAccount, accountQuery);
        return accountDao.selectList(handleParams(accountQuery));
    }

    @Override
    @Transactional
    public ResultJson createAccountAdmin(Account account, List<Integer> enterpriseIds, List<Integer> projectIds, List<Integer> roleIds) {
        //设置初始密码
        if (StringUtils.isEmpty(account.getPassword())) {
            account.setPassword(DEFAULT_PWD);
        }
        //插入账号信息
        accountDataVerify(account);
        //业态下，手机号 唯一 / 账号 唯一
        accountUnique(account);
        //根据角色反查项目ids 和企业ids
        Map<String, List<Integer>> entAndProIdMap = convertEntAndProIdMap(account, enterpriseIds, projectIds, roleIds);
        List<Integer> resultEntIdList = entAndProIdMap.get("entIdList");
        List<Integer> resultProIdList = entAndProIdMap.get("proIdList");
        //密码加密
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String pwdEncode = bCryptPasswordEncoder.encode(account.getPassword());
        account.setPassword(pwdEncode);
        if (null == account.getType()) {
            // 默认设置普通账号
            account.setType((short) 1);
        }
        if (null == account.getCertification()) {
            account.setCertification(false);
        }
        accountDao.insert(account);
        updatePermissionGroup(roleIds, projectIds, account.getId());
        try {
            accountRelationUpdate(account.getId(), resultEntIdList, resultProIdList, roleIds);
        } catch (Exception e) {
            e.printStackTrace();
            throw new DataException("账号关联数据更新失败");
        }

        Account accountDb = findById(account.getId());
        //记录操作日志
        accountLogRecord(null, LogOperationTypeEnum.CREATE, "新增账号" + "【" + accountDb.getLoginName() + "】");
        return ResultJson.success("操作成功", account.getId());
    }

    @Override
    public ResultJson updateAccountAdmin(Account account, List<Integer> enterpriseIds, List<Integer> projectIds, List<Integer> roleIds) {
        if (Objects.isNull(account.getId())) {
            throw new DataException("缺少账号数据");
        }
        //手机号校验
        //不允许 空格串和空数据
        if (StringUtils.isNotEmpty(account.getPhone())) {
            //不允许 除数字外
            if (!DataVerifyUtil.isNumber(account.getPhone())) {
                throw new DataException("手机号只允许输入数字");
            }
            //不允许 非 11位
            if (!DataVerifyUtil.isFixedLengthString(11, account.getPhone())) {
                throw new DataException("手机号只允许输入11位数字");
            }
        }
        //账号登录名不允许包含空格
        if (StringUtils.isNotEmpty(account.getLoginName())) {
            if (account.getLoginName().contains(" ")) {
                throw new DataException("账号登录名不能包含空格");
            }
        }
        //填充加密后的密码
        if (Objects.nonNull(account.getPassword())) {
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            String pwdEncode = bCryptPasswordEncoder.encode(account.getPassword());
            account.setPassword(pwdEncode);
        }
        Account accountExist = accountDao.selectById(account.getId());
        if (Objects.isNull(accountExist)) {
            log.info("检测到账号数据不存在，id={}", account.getId());
            throw new DataException("账号数据不存在");
        }
        //业态下，手机号 唯一 / 账号 唯一
        accountUnique(account);
        UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", account.getId());
        accountDao.update(account, updateWrapper);
        Account accountDb = findById(account.getId());
        //记录操作日志
        accountLogRecord(null, LogOperationTypeEnum.UPDATE, "编辑账号" + "【" + accountDb.getLoginName() + "】");
        return ResultJson.success("操作成功");
    }

    @Override
    public ResultJson deleteAccountAdmin(Integer accountId) {
        //需要删除关联表数据，如果全部关联数据都删除则执行逻辑删除
        accountRoleService.deleteAccountRole(Arrays.asList(accountId), null);
        UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", accountId);
        updateWrapper.set("is_deleted", true);
        update(updateWrapper);
        Account accountDb = findById(accountId);
        //记录操作日志
        accountLogRecord(null, LogOperationTypeEnum.DELETE, "删除账号" + "【" + accountDb.getLoginName() + "】");
        return ResultJson.success("操作成功");
    }


    /**
     * 动态查找 超管、企管、项管
     *
     * @param roleType
     * @param roleGrade
     * @param accountIdList
     * @return
     */
    @Override
    public List<Integer> getAdminAccountDynamic(Integer roleType, Short roleGrade, List<Integer> accountIdList) {
        List<Integer> adminAccountDynamic = accountDao.getAdminAccountDynamic(roleType, roleGrade, accountIdList);
        return adminAccountDynamic;
    }

    @Override
    public Page<Account> page(AccountCriteria accountCriteria, Page page) {
        Page<Account> page1 = accountDao.page(page, accountCriteria);
        return page1;
    }

    @Override
    public Page<AccountDTO> page(AccountQuery accountQuery, Page page) {
        QueryWrapper<Account> accountQueryWrapper = new QueryWrapper<>();
        accountQueryWrapper.select("id", "login_name", "name", "nickname", "phone", "sex", "age", "email",
                "status", "updated_at", "created_at", "id_card", "develop_id", "type", "certification");
        paramHandler(accountQueryWrapper, accountQuery);
        Page accountPage = accountDao.selectPage(page, accountQueryWrapper);
        List<AccountDTO> records = viewHandler(accountPage.getRecords());
        if (null != accountQuery.getDevelopId()) {
            Developer developer = developerDao.selectById(accountQuery.getDevelopId());
            if (null != developer) {
                for (AccountDTO record : records) {
                    if (record.getId().equals(developer.getAccountId())) {
                        record.setVType("主账号");
                    } else {
                        record.setVType("子账号");
                    }
                }
            }
        }
        accountPage.setRecords(records);
        return accountPage;
    }

    @Override
    public Page<AccountDTO> complexPage(AccountQuery accountQuery, Page page) {
        Page<AccountDTO> accountDTOPage = accountDao.complexPage(page, accountQuery);
        fillAccountData(accountQuery, accountDTOPage.getRecords(), true);
        return accountDTOPage;
    }

    /**
     * 返回值回写
     *
     * @param accounts
     * @return
     */
    private List<AccountDTO> viewHandler(List<Account> accounts) {

        if (CollectionUtils.isEmpty(accounts)) {
            return Collections.emptyList();
        }
        // 角色回显
        List<Integer> accountIds = accounts.stream().map(i -> i.getId()).collect(Collectors.toList());
        Map<Integer, List<Role>> roleMap = roleService.batchRoleMap(accountIds);
        List<AccountDTO> accountDTOS = new ArrayList<>(accounts.size());
        for (Account account : accounts) {
            AccountDTO accountDTO = new AccountDTO();
            BeanUtils.copyProperties(account, accountDTO);
            List<Role> roles = roleMap.get(account.getId());
            if (!CollectionUtils.isEmpty(roles)) {
                accountDTO.setRoleIds(roles.stream().map(i -> i.getId()).collect(Collectors.toList()));
                accountDTO.setRoleNames(roles.stream().map(i -> i.getName()).collect(Collectors.toList()));
                accountDTO.setRoles(roles);
            }
            accountDTOS.add(accountDTO);
        }
        return accountDTOS;
    }

    private void paramHandler(QueryWrapper<Account> queryWrapper, AccountQuery accountQuery) {
        if (!CollectionUtils.isEmpty(accountQuery.getTypes())) {
            queryWrapper.in("type", accountQuery.getTypes());
        }
        if (StringUtils.isNotEmpty(accountQuery.getDevelopCode())) {
            QueryWrapper<Developer> developerQueryWrapper = new QueryWrapper<>();
            developerQueryWrapper.eq("code", accountQuery.getDevelopCode());
            Developer developer = developerDao.selectOne(developerQueryWrapper);
            if (null != developer) {
                accountQuery.setDevelopId(developer.getId());
            }
        }
        if (StringUtils.isNotEmpty(accountQuery.getLikeSearch())) {
            queryWrapper.and(wrapper -> wrapper.like("login_name", accountQuery.getLikeSearch())
                    .or().like("phone", accountQuery.getLikeSearch())
                    .or().like("name", accountQuery.getLikeSearch())
                    .or().like("email", accountQuery.getLikeSearch()));
        }

        if (!CollectionUtils.isEmpty(accountQuery.getRoleIdList())) {
            QueryWrapper<AccountRole> accountRoleQueryWrapper = new QueryWrapper<>();
            accountRoleQueryWrapper.select("account_id");
            accountRoleQueryWrapper.in("role_id", accountQuery.getRoleIdList());

            List<AccountRole> accountRoles = accountRoleDao.selectList(accountRoleQueryWrapper);
            if (accountRoles.isEmpty()) {
                log.warn("没有关联角色的帐号");
                queryWrapper.eq("id", -1);
            } else {
                queryWrapper.in("id", accountRoles.stream().map(i -> i.getAccountId()).collect(Collectors.toList()));
            }
        }
        // 开发者信息为必填
        if (null != accountQuery.getDevelopId()) {
            queryWrapper.eq("develop_id", accountQuery.getDevelopId());
        } else if (null != accountQuery.getId() || !CollectionUtils.isEmpty(accountQuery.getIdList())) {
            if (null != accountQuery.getId()) {
                queryWrapper.eq("id", accountQuery.getId());
            }
            if (!CollectionUtils.isEmpty(accountQuery.getIdList())) {
                queryWrapper.in("id", accountQuery.getIdList());
            }
        }
        if(null != accountQuery.getStatus()){
            queryWrapper.eq("status", accountQuery.getStatus());
        }
    }

    @Override
    public Account phoneExist(String phone, Short industryId) {
        QueryWrapper<Account> accountQueryWrapper = new QueryWrapper<>();
        accountQueryWrapper.eq("phone", phone);
        accountQueryWrapper.eq("industry_id", industryId);
        accountQueryWrapper.eq("is_deleted", false);
        List<Account> list = list(accountQueryWrapper);
        if (list.size() > 1) {
            log.warn("数据错误，根据手机号 {} 查询到了多个帐号 {}", phone, list);
        }
        if (list.size() > 0) {
            return list.get(0);
        } else {
            return null;
        }
    }

    @Override
    public Account phoneExistV2(String phone, Integer developId) {
        QueryWrapper<Account> accountQueryWrapper = new QueryWrapper<>();
        accountQueryWrapper.eq("phone", phone);
        accountQueryWrapper.eq("develop_id", developId);
        accountQueryWrapper.eq("is_deleted", false);
        List<Account> list = list(accountQueryWrapper);
        if (list.size() > 1) {
            log.warn("数据错误，根据手机号 {} 查询到了多个帐号 {}", phone, list);
        }
        if (list.size() > 0) {
            return list.get(0);
        } else {
            return null;
        }
    }

    /**
     * 根据账号id 查找出关联角色的信息以及账号信息
     *
     * @param accountIdList
     * @return
     */
    @Deprecated
    @Override
    public List<AccountDetailDTO> getAccountRoleInfoByIdList(List<Integer> accountIdList, List<Integer> roleIdList) {
        return accountDao.getAccountRoleInfoByIdList(accountIdList, roleIdList);
    }


    // 动态查找 账号&角色 （局部内部查找，只关联账号、角色表）
    @Override
    public List<AccountDetailDTO> getAccountRoleDynamic(AccountRoleQuery accountRoleQuery) {

        return accountDao.getAccountRoleDynamic(accountRoleQuery);
    }


    @Override
    public Page<AccountDetailDTO> getPageAccountRoleInfoByIdList(Page page, List<Integer> accountIdList, List<Integer> roleIdList) {
        return accountDao.getPageAccountRoleInfoByIdList(page, accountIdList, roleIdList);
    }


    /**
     * 查询企业管理员
     *
     * @param enterpriseId
     * @return
     */
    private List<Integer> enterpriseAdminAccount(List<Integer> enterpriseId) {
        QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
        roleQueryWrapper.select("id");
        roleQueryWrapper.eq("type", RoleTypeEnum.MANAGER.code);
        roleQueryWrapper.eq("grade", BusinessType.ENTERPRISE.code);
        roleQueryWrapper.in("enterprise_id", enterpriseId);
        List<Role> roles = roleDao.selectList(roleQueryWrapper);
        List<Integer> roleIds = roles.stream().map(e -> e.getId()).collect(Collectors.toList());
        List<Integer> accountIds = accountRoleService.findByRoleId(roleIds);
        return accountIds;
    }


    /**
     * 查询超级管理员
     *
     * @return
     */
    public List<Integer> superAdminAccount(List<Short> industryIds) {
        QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
        roleQueryWrapper.select("id");
        roleQueryWrapper.in("industry_id", industryIds);
        roleQueryWrapper.eq("type", RoleTypeEnum.SUPPER_MANAGER.code);
        List<Role> roles = roleDao.selectList(roleQueryWrapper);
        List<Integer> roleIds = roles.stream().map(Role::getId).collect(Collectors.toList());
        List<Integer> accountIds = accountRoleService.findByRoleId(roleIds);
        return accountIds;
    }


    /**
     * 根据账号id 查找出关联项目的信息以及账号信息
     *
     * @param accountIdList
     * @return
     */
    @Override
    public List<AccountDetailDTO> getAccountProjectInfoByIdList(List<Integer> accountIdList) {
        return accountDao.getAccountProjectInfoByIdList(accountIdList);
    }

    /**
     * 根据主键 查找账号信息
     *
     * @param id
     * @return
     */
    @Override
    public Account findById(Integer id) {
        if (Objects.isNull(id)) {
            throw new DataException("缺少账号数据");
        }
        return accountDao.selectById(id);

    }

    /**
     * 创建账号
     *
     * @param account
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultJson createAccount(Account account, List<Integer> enterpriseIds, List<Integer> projectIds, List<Integer> roleIds) {
        ResultJson<Integer> accountOrigin = createAccountOrigin(account, enterpriseIds, projectIds, roleIds);
        // 创建权限组
        if (accountOrigin.getState()) {
            updatePermissionGroup(roleIds, projectIds, accountOrigin.getResult());
        }
        createSendToMQ(account);
        return accountOrigin;
    }

    /**
     * 旧账号方法 创建or更新权限组信息
     *
     * @param roleIds
     * @param projectIds 权限分组的标准 一个项目id分一个权限组
     * @param accountId
     */
    private void updatePermissionGroup(List<Integer> roleIds, List<Integer> projectIds, Integer accountId) {
        if (CollectionUtils.isEmpty(roleIds)) {
            log.warn("保存权限组角色信息为空");
            return;
        }
        List<PermissionGroupDTO> permissionGroups = new ArrayList<>();

        // 一个项目一个权限组 权限组里的项目都是该项目下的权限， 不是项目权限的放到没有项目的权限组
        List<Role> roles = roleService.listByIds(roleIds);
        if (CollectionUtils.isEmpty(roles)) {
            log.warn("保存权限组角色信息为空");
            return;
        }
//        if(CollectionUtils.isEmpty(projectIds)){
        // 全部角色放到一个权限组里
        PermissionGroupDTO permissionGroupDTO = new PermissionGroupDTO();
        permissionGroupDTO.setProjectList(projectIds);
        permissionGroupDTO.setRoleList(roleIds);
        permissionGroups.add(permissionGroupDTO);
//        }else{
//            List<Project> projects = projectDao.selectBatchIds(projectIds);
//            for (Project project : projects) {
//                PermissionGroupDTO permissionGroupDTO = new PermissionGroupDTO();
//                // 不过滤项目角色了 新业务没有项目级角色
//                List<Integer> collect = roles.stream().map(j -> j.getId()).collect(Collectors.toList());
//                permissionGroupDTO.setRoleList(collect);
//                permissionGroupDTO.setProjecList(Arrays.asList(project.getId()));
//                permissionGroups.add(permissionGroupDTO);
//            }
//        }
        log.info("用户 {} 保存权限组信息 {} 条", accountId, permissionGroups.size());
        savePermissionGroup(accountId, permissionGroups);
    }

    /**
     * 新增权限分组，对已有的权限先进行判断
     *
     * @param roleIds
     * @param projectIds
     * @param accountId
     */
    private void addPermissionGroup(List<Integer> roleIds, List<Integer> projectIds, Integer accountId) {
        log.info("添加权限：roleIds={},projectIds={},accountId={}", JSONObject.toJSONString(roleIds), JSONObject.toJSONString(projectIds), accountId);
        if (CollectionUtils.isEmpty(roleIds))
            return;
        List<PermissionGroup> list = permissionGroupService.list(new LambdaQueryWrapper<PermissionGroup>().eq(PermissionGroup::getAccountId, accountId));
        List<PermissionGroupDTO> listDTO = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            List<PermissionGroupDTO> collect1 = list.stream().map(permissionGroup -> {
                PermissionGroupDTO permissionGroupDTO = new PermissionGroupDTO();
                permissionGroupDTO.setAccountId(accountId);
                String projectIds1 = permissionGroup.getProjectIds();
                if (StringUtils.isNotEmpty(projectIds1)) {
                    List<Integer> collect = Arrays.asList(projectIds1.split(",")).stream().map(projectId -> Integer.parseInt(projectId)).collect(Collectors.toList());
                    permissionGroupDTO.setProjectList(collect);
                }
                String roleIds1 = permissionGroup.getRoleIds();
                if (StringUtils.isNotEmpty(roleIds1)) {
                    List<Integer> collect = Arrays.asList(roleIds1.split(",")).stream().map(roleId -> Integer.parseInt(roleId)).collect(Collectors.toList());
                    permissionGroupDTO.setRoleList(collect);
                }
                return permissionGroupDTO;
            }).collect(Collectors.toList());
            listDTO.addAll(collect1);
        }
        //现有权限是否已包含待新增权限
        boolean isContainer = false;
        if (!CollectionUtils.isEmpty(list)) {
            if (CollectionUtils.isEmpty(projectIds)) {
                isContainer = listDTO.stream().filter(permissionGroupDTO ->
                        CollectionUtils.isEmpty(permissionGroupDTO.getProjectList())
                                && permissionGroupDTO.getRoleList().containsAll(roleIds)
                ).findFirst().isPresent();
            } else {
                isContainer = listDTO.stream().filter(permissionGroupDTO ->
                        permissionGroupDTO.getProjectList() != null
                                && permissionGroupDTO.getRoleList() != null
                                && permissionGroupDTO.getProjectList().containsAll(projectIds)
                                && permissionGroupDTO.getRoleList().containsAll(roleIds)
                ).findFirst().isPresent();
            }
        }
        if (isContainer) {
            log.info("已有权限已覆盖需要新增的权限");
        } else {
            PermissionGroupDTO permissionGroupDTO = new PermissionGroupDTO();
            permissionGroupDTO.setProjectList(projectIds);
            permissionGroupDTO.setRoleList(roleIds);
            listDTO.add(permissionGroupDTO);
            log.info("权限保存动作：{}", JSONObject.toJSONString(listDTO));
            savePermissionGroup(accountId, listDTO);
        }
    }

    @Override
    public ResultJson<Integer> createAccountV2(Account account, AccountRelation relation, List<PermissionGroupDTO> permissionGroupDTOList) {
        ResultJson<Integer> accountOrigin = createAccountOrigin(account, relation.getEnterpriseIds(), relation.getProjectIds(), relation.getRoleIds());

        // 保存权限组信息
        if (accountOrigin.getState()) {
            savePermissionGroup(accountOrigin.getResult(), permissionGroupDTOList);
        }
        createSendToMQ(account);
        return accountOrigin;
    }

    private ResultJson createAccountOrigin(Account account, List<Integer> enterpriseIds, List<Integer> projectIds, List<Integer> roleIds) {
        //设置初始密码
        if (StringUtils.isEmpty(account.getPassword())) {
            account.setPassword(DEFAULT_PWD);
        }
        //角色ID去重,有可能前端传入重复参数
        if (ChkUtil.isNotNull(roleIds)) {
            roleIds = roleIds.stream().distinct().collect(Collectors.toList());
        }
        //判断roleIds是否包含 内置角色，区分来自业态后端的新增操作
        // 填充默认的开发者
        if (null == account.getDevelopId()) {
            account.setDevelopId(developerService.getDefault().getId());
        }
        // 默认男
        if(null == account.getSex()){
            account.setSex((short) 1);
        }
        accountDataVerify(account);
        //手机号 唯一 / 账号 唯一
        accountUnique(account);
        //根据角色反查项目ids 和企业ids
        Map<String, List<Integer>> entAndProIdMap = convertEntAndProIdMap(account, enterpriseIds, projectIds, roleIds);
        List<Integer> resultEntIdList = entAndProIdMap.get("entIdList");
        List<Integer> resultProIdList = entAndProIdMap.get("proIdList");

        //密码加密
        account.setPassword(encode(account));
        if (StringUtils.isNotEmpty(account.getName())) {
            String nameCovert = EmojiParser.parseToAliases(account.getName());
            account.setName(nameCovert);
        }
        if (StringUtils.isNotEmpty(account.getNickname())) {
            String nickNameCovert = EmojiParser.parseToAliases(account.getNickname());
            account.setNickname(nickNameCovert);
        }
        if (null == account.getType()) {
            account.setType((short) 1);
        }
        if (null == account.getCertification()) {
            account.setCertification(false);
        }
        accountDao.insert(account);
        try {
            accountRelationUpdate(account.getId(), resultEntIdList, resultProIdList, roleIds);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("账号关联数据更新失败 {}", e.getMessage());
            throw new DataException("账号关联数据更新失败");
        }
        //维护  账号、 业态角色 、 项目 之间的关系
        holdAccountInitRole(account, projectIds, roleIds, OperationTypeEnum.CREATE.getType());

        Account accountDb = findById(account.getId());
        //记录操作日志
        accountLogRecord(null, LogOperationTypeEnum.CREATE, "创建账号" + "【" + accountDb.getLoginName() + "】");
        return ResultJson.success("操作成功", account.getId());
    }

    private void createSendToMQ(Account account) {
        //推送到Kafka账号新增主题
        AccountDTO pushAccount = new AccountDTO();
        try {
            AccountQuery accountQuery = new AccountQuery();
            accountQuery.setIdList(Arrays.asList(account.getId()));
            List<AccountDTO> list = getList(accountQuery);

            if (!CollectionUtils.isEmpty(list)) {
                pushAccount = list.get(0);
                pushAccount.setPassword(account.getPassword());
                pushAccount.setIdCard(account.getIdCard());
                accountProducer.createPush(JSON.toJSONString(pushAccount));
            }
        } catch (Exception e) {
            log.info("当前账号数据推送到新增主题异常,账号数据={}", pushAccount.toString());
        }
    }

    /**
     * 保存权限组信息 先删除后新增
     *
     * @param accountId
     * @param permissionGroupDTOS
     */
    private void savePermissionGroup(Integer accountId, List<PermissionGroupDTO> permissionGroupDTOS) {
        // 先删除后新增
        QueryWrapper<PermissionGroup> permissionGroupQueryWrapper = new QueryWrapper<>();
        permissionGroupQueryWrapper.eq("account_id", accountId);
        permissionGroupQueryWrapper.eq("enterprise_id",permissionGroupDTOS.get(0).getEnterpriseId());
        permissionGroupService.remove(permissionGroupQueryWrapper);
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(permissionGroupDTOS)) {
            log.warn("该账号 {} 没有权限信息");
            return;
        }
        createPermissionGroup(accountId, permissionGroupDTOS);
    }

    /**
     * 创建权限组信息
     * @param accountId
     * @param permissionGroupDTOS
     */
    private void createPermissionGroup(Integer accountId, List<PermissionGroupDTO> permissionGroupDTOS){
        List<PermissionGroup> permissionGroups = new ArrayList<>(permissionGroupDTOS.size());

        QueryWrapper<PermissionGroup> permissionGroupQueryWrapper = new QueryWrapper<>();
        permissionGroupQueryWrapper.eq("account_id", accountId);
        List<PermissionGroup> oldGroup = permissionGroupService.list(permissionGroupQueryWrapper);
        Integer entId = permissionGroupDTOS.get(0).getEnterpriseId();
        for (PermissionGroupDTO permissionGroupDTO : permissionGroupDTOS) {
            PermissionGroup permissionGroup = new PermissionGroup();
            List<Integer> roleIds = permissionGroupDTO.getRoleList();
            if (org.apache.commons.collections4.CollectionUtils.isEmpty(roleIds)) {
                throw new BusinessException("缺少角色信息");
            }
            roleIds = roleIds.stream().distinct().collect(Collectors.toList());
            permissionGroup.setRoleIds(Joiner.on(",").skipNulls().join(roleIds));
            List<Integer> projectIds = permissionGroupDTO.getProjectList();
            if (!org.apache.commons.collections4.CollectionUtils.isEmpty(projectIds)) {
                projectIds = projectIds.stream().distinct().collect(Collectors.toList());
                permissionGroup.setProjectIds(Joiner.on(",").skipNulls().join(projectIds));
            }
            // 重复的不再添加

            permissionGroup.setAccountId(accountId);
            //填充企业id
            if (null != entId){
                permissionGroup.setEnterpriseId(entId);
            }
            if(!isRepeat(permissionGroup, oldGroup)){
                permissionGroups.add(permissionGroup);
            }
        }
        permissionGroupService.saveBatch(permissionGroups);
    }

    /**
     * oldGroup 是否包含了 newGroup 权限组，包含返回true
     * @param newGroup
     * @param oldGroup
     * @return
     */
    private boolean isRepeat(PermissionGroup newGroup, List<PermissionGroup> oldGroup){
        for (PermissionGroup permissionGroup : oldGroup) {
            if(permissionGroup.getAccountId().equals(newGroup.getAccountId())
                    && projectIsEquals(permissionGroup.getProjectIds(), newGroup.getProjectIds())
                    && permissionGroup.getRoleIds().equals(newGroup.getRoleIds())){
                return true;
            }
        }
        return false;
    }

    /**
     * 判断两个项目id集合是否相等
     * @param projectIdsNew
     * @param projectIdsOlds
     * @return
     */
    private static boolean projectIsEquals(String projectIdsNew, String projectIdsOlds){
        return ObjectUtils.nullSafeEquals(projectIdsNew, projectIdsOlds);
    }

    private String encode(Account account) {
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String pwdEncode = bCryptPasswordEncoder.encode(account.getPassword());
        return pwdEncode;
    }

    /**
     * 第三方账号开户 （创建账号 & 绑定 第三方openId）
     *
     * @param establishOpenAccount
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultJson establishOpenAccount(EstablishOpenAccount establishOpenAccount) {
        if (null == establishOpenAccount.getOpenId()) {
            return ResultJson.fail("第三方账号唯一标识不能为空");
        }
        if (null == establishOpenAccount.getAccount()) {
            return ResultJson.fail("账号数据不能为空");
        }
        Account account = establishOpenAccount.getAccount();
        ResultJson createResult = createAccount(account, establishOpenAccount.getEnterpriseIds(), establishOpenAccount.getProjectIds(), establishOpenAccount.getRoleIds());
        if (!CodeEnum.SUCCESS.getCode().equals(createResult.getCode())) {
            return createResult;
        }
        //执行绑定openId
        Integer accountId = account.getId();
        String openId = establishOpenAccount.getOpenId();
        String appId = establishOpenAccount.getAppId();
        //根据appId 查找出 第三方账号系统标识 后期应该在配置表内呈现关联关系
        OpenConfigQuery openConfigQuery = new OpenConfigQuery();
        openConfigQuery.setAppId(appId);
        OpenConfig openConfig = openConfigService.findOne(openConfigQuery);
        if (Objects.isNull(openConfig)) {
            log.info("config表查找不到该第三方appId的相关配置参数，appId={}", appId);
            return ResultJson.fail("获取不到相关app参数");
        }
        Short openType = openConfig.getOpenType();
        //绑定
        log.info("正在执行账号绑定,绑定参数openType={},accountId={},openId={},appId={}", openType, accountId, openId, appId);

        AccountOpenAuth openIdCheck = new AccountOpenAuth();
        openIdCheck.setOpenId(openId);
        openIdCheck.setType(openType);
        openIdCheck.setAppId(appId);
        AccountOpenAuth openIdExistCheck = accountOpenAuthService.getOne(openIdCheck);
        if (null != openIdExistCheck) {
            if (ThirdAccountTypeEnum.WE_CHAT.getType().equals(openType)) {
                return ResultJson.fail(CodeEnum.OPENID_WECHAT_BIND_EXIST.getCode(), CodeEnum.OPENID_WECHAT_BIND_EXIST.getDescription());
            }
            return ResultJson.fail("当前第三方账号唯一标识已经被绑定");
        }
        AccountOpenAuth accountIdCheck = new AccountOpenAuth();
        accountIdCheck.setType(openType);
        accountIdCheck.setAccountId(accountId);
        accountIdCheck.setAppId(appId);
        AccountOpenAuth accountIdExistCheck = accountOpenAuthService.getOne(accountIdCheck);
        if (null != accountIdExistCheck) {
            if (ThirdAccountTypeEnum.WE_CHAT.getType().equals(openType)) {
                return ResultJson.fail(CodeEnum.ACCOUNT_WECHAT_BIND_EXIST.getCode(), CodeEnum.ACCOUNT_WECHAT_BIND_EXIST.getDescription());
            }
            return ResultJson.fail("当前账号已经被其他第三方唯一标识绑定");
        }
        AccountOpenAuth createAccountOpenAuth = new AccountOpenAuth();
        createAccountOpenAuth.setAccountId(accountId);
        createAccountOpenAuth.setOpenId(openId);
        createAccountOpenAuth.setType(openType);
        createAccountOpenAuth.setAppId(appId);
        ResultJson createAccountOpenAuthResult = accountOpenAuthService.create(createAccountOpenAuth);
        if (createAccountOpenAuthResult.getCode().equals(CodeEnum.SUCCESS.getCode())) {
            return ResultJson.success("操作成功", accountId);
        }

        return ResultJson.fail("操作失败");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultJson deleteCoreAccount(Integer accountId) {

        log.info("正在执行删除账号，需要删除的账号id={}", accountId);
        if (null == accountId) {
            throw new DataException("缺少账号信息");
        }

        //账号组织表数据 删除
        QueryWrapper<AccountOrganization> accountOrganizationQueryWrapper = new QueryWrapper<>();
        accountOrganizationQueryWrapper.eq("account_id", accountId);
        accountOrganizationService.remove(accountOrganizationQueryWrapper);

        //账号项目表数据 删除
        QueryWrapper<AccountProject> accountProjectQueryWrapper = new QueryWrapper<>();
        accountProjectQueryWrapper.eq("account_id", accountId);
        accountProjectService.remove(accountProjectQueryWrapper);

        //账号角色表数据 删除
        QueryWrapper<AccountRole> accountRoleQueryWrapper = new QueryWrapper<>();
        accountRoleQueryWrapper.eq("account_id", accountId);
        accountRoleService.remove(accountRoleQueryWrapper);

        //账号第三方绑定表数据 删除
        QueryWrapper<AccountOpenAuth> accountOpenAuthQueryWrapper = new QueryWrapper<>();
        accountOpenAuthQueryWrapper.eq("account_id", accountId);
        accountOpenAuthService.remove(accountOpenAuthQueryWrapper);

        //账号用户组表数据 删除
        QueryWrapper<GroupAccount> groupAccountQueryWrapper = new QueryWrapper<>();
        accountOpenAuthQueryWrapper.eq("account_id", accountId);
        groupAccountService.remove(groupAccountQueryWrapper);

        //账户表
        UpdateWrapper<Account> updateWrapper = new UpdateWrapper();
        updateWrapper.eq("id", accountId);
        Account account = new Account();
        account.setId(accountId);
        account.setIsDeleted(true);
        //更新删除字段 is_deleted
        Boolean updateResult = update(account, updateWrapper);
        if (!updateResult) {
            throw new DataException("删除账号失败");
        }
        return ResultJson.success("操作成功");
    }

    @Override
    public ResultJson deleteCoreAccountBatch(List<Integer> accountIdList) {

        try {
            if (!CollectionUtils.isEmpty(accountIdList)) {
                //删除账号、项目关联关系
                QueryWrapper<AccountProject> accountProjectQueryWrapper = new QueryWrapper<>();
                accountProjectQueryWrapper.in("account_id", accountIdList);
                accountProjectService.remove(accountProjectQueryWrapper);
                //账号、（项目的）组织关联关系
                QueryWrapper<AccountOrganization> accountOrganizationQueryWrapper = new QueryWrapper<>();
                accountOrganizationQueryWrapper.in("account_id", accountIdList);
                accountOrganizationService.remove(accountOrganizationQueryWrapper);

                //账号角色表数据 删除
                QueryWrapper<AccountRole> accountRoleQueryWrapper = new QueryWrapper<>();
                accountRoleQueryWrapper.in("account_id", accountIdList);
                accountRoleService.remove(accountRoleQueryWrapper);

                //账号第三方绑定表数据 删除
                QueryWrapper<AccountOpenAuth> accountOpenAuthQueryWrapper = new QueryWrapper<>();
                accountOpenAuthQueryWrapper.in("account_id", accountIdList);
                accountOpenAuthService.remove(accountOpenAuthQueryWrapper);

                //账号用户组表数据 删除
                QueryWrapper<GroupAccount> groupAccountQueryWrapper = new QueryWrapper<>();
                accountOpenAuthQueryWrapper.in("account_id", accountIdList);
                groupAccountService.remove(groupAccountQueryWrapper);


                //执行账号移除
                UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
                updateWrapper.in("id", accountIdList);
                updateWrapper.set("is_deleted", true);
                update(updateWrapper);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("批量删除账号失败，accountIdList={}", accountIdList.toString());
        }
        return ResultJson.success("操作成功");

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultJson updateCoreAccount(Account account, List<Integer> enterpriseIds, List<Integer> projectIds, List<Integer> roleIds) {

        if (Objects.isNull(account.getId())) {
            throw new DataException("缺少账号数据");
        }
        //手机号校验
        //不允许 空格串和空数据
        if (StringUtils.isNotEmpty(account.getPhone())) {
            //不允许 除数字外
            if (!DataVerifyUtil.isNumber(account.getPhone())) {
                throw new DataException("手机号只允许输入数字");
            }
            //不允许 非 11位
            if (!DataVerifyUtil.isFixedLengthString(11, account.getPhone())) {
                throw new DataException("手机号只允许输入11位数字");
            }
        }
        //账号登录名不允许包含空格
        if (StringUtils.isNotEmpty(account.getLoginName())) {
            if (account.getLoginName().contains(" ")) {
                throw new DataException("账号登录名不能包含空格");
            }
        }
        //填充加密后的密码
        String originalPassword = account.getPassword();
        if (Objects.nonNull(account.getPassword())) {
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            String pwdEncode = bCryptPasswordEncoder.encode(account.getPassword());
            account.setPassword(pwdEncode);
        }
        Account accountExist = accountDao.selectById(account.getId());
        if (Objects.isNull(accountExist)) {
            log.info("检测到账号数据不存在，id={}", account.getId());
            throw new DataException("账号数据不存在");
        }
        account.setDevelopId(accountExist.getDevelopId());
        //业态下 账号唯一、手机号、邮箱 唯一验重
        accountUnique(account);
        //根据角色反查项目ids 和企业ids
        Map<String, List<Integer>> entAndProIdMap = convertEntAndProIdMap(account, enterpriseIds, projectIds, roleIds);
        List<Integer> resultEntIdList = entAndProIdMap.get("entIdList");
        List<Integer> resultProIdList = entAndProIdMap.get("proIdList");
        Integer accountId = account.getId();

        //针对不跨企业作校验
        //把当前账号关联的企业数据查出来，比较需要插入的企业数据，判断是否有不对称数据
        if (crossEnterpriseVerify(resultEntIdList, accountId)) {
            return ResultJson.fail("修改失败,当前账号已经关联其他企业，不允许跨企业账号");
        }
        try {
            if (StringUtils.isNotEmpty(account.getName())) {
                String nameCovert = EmojiParser.parseToAliases(account.getName());
                account.setName(nameCovert);
            }
            if (StringUtils.isNotEmpty(account.getNickname())) {
                String nickNameCovert = EmojiParser.parseToAliases(account.getNickname());
                account.setNickname(nickNameCovert);
            }
            UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", account.getId());
            int effectNumUpdate = accountDao.update(account, updateWrapper);
            if (effectNumUpdate != 1) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                throw new DataException("更新账号数据失败");
            }

            //先删除后新增， 新增取决于 传入的 企业、项目、角色 参数
            //删除 账号-组织关联表
            QueryWrapper<AccountOrganization> orgQueryWrapper = new QueryWrapper<>();
            orgQueryWrapper.eq("account_id", accountId);
            orgQueryWrapper.in("type", Arrays.asList(OrganizationTypeEnum.ENTERPRISE.id, OrganizationTypeEnum.PROJECT.id));
            accountOrganizationService.remove(orgQueryWrapper);

            //新增 账号-组织关联表
            if (!CollectionUtils.isEmpty(resultProIdList)) {
                QueryWrapper<Project> proQueryWrapper = new QueryWrapper<>();
                proQueryWrapper.in("id", resultProIdList);
                List<Project> proList = projectDao.selectList(proQueryWrapper);
                saveAccountOrganizationProject(proList, accountId);
            } else if (!CollectionUtils.isEmpty(resultEntIdList)) {
                QueryWrapper<Enterprise> entQueryWrapper = new QueryWrapper<>();
                entQueryWrapper.in("id", resultEntIdList);
                List<Enterprise> entList = enterpriseDao.selectList(entQueryWrapper);
                saveAccountOrganizationEnterprise(entList, accountId);
            }
            //删除 账号-项目关联表
            accountProjectService.delete(Arrays.asList(accountId), null);
            //新增 账号-项目关联表
            if (!CollectionUtils.isEmpty(resultProIdList)) {
                accountProjectService.insert(accountId, resultProIdList);
            }
            //删除账号-角色
            accountRoleService.deleteAccountRole(Arrays.asList(accountId), null);
            //新增账号-角色
            accountRoleService.insertAccountRole(accountId, roleIds);
        } catch (Exception e) {
            e.printStackTrace();
            throw new DataException("更新账号数据失败" + e.getMessage());
        }
        //维护  账号、 业态角色 、 项目 之间的关系
        holdAccountInitRole(account, projectIds, roleIds, OperationTypeEnum.UPDATE.getType());
        Account accountDb = findById(account.getId());
        //记录操作日志
        accountLogRecord(null, LogOperationTypeEnum.UPDATE, "编辑账号" + "【" + accountDb.getLoginName() + "】");

        //推送到Kafka账号更新主题
        AccountDTO pushAccount = new AccountDTO();
        try {
            AccountQuery accountQuery = new AccountQuery();
            accountQuery.setIdList(Arrays.asList(account.getId()));
            List<AccountDTO> list = getList(accountQuery);
            if (!CollectionUtils.isEmpty(list)) {
                pushAccount = list.get(0);
                pushAccount.setPassword(originalPassword);
                pushAccount.setIdCard(account.getIdCard());
                accountProducer.updatePush(JSON.toJSONString(pushAccount));
            }
        } catch (Exception e) {
            log.info("当前账号数据推送到更新主题异常,账号数据={}", pushAccount.toString());
        }

        return ResultJson.success("操作成功");

    }

    @Override
    public void addProjectToAccount(Integer accountId, List<Integer> roles, List<Integer> projectIds) {
        if (CollectionUtils.isEmpty(projectIds)) {
            return;
        }
        //新增权限
        addPermissionGroup(roles, projectIds, accountId);
        //查询已有关联,已关联的项目不处理，注意projectIds会被修改
        List<Integer> list = accountProjectService.list(accountId, null);
        if (!CollectionUtils.isEmpty(list)) {
            //过滤已有的projectId关联
            projectIds = projectIds.stream().filter(id -> !list.contains(id)).collect(Collectors.toList());
        }
        if (!CollectionUtils.isEmpty(projectIds)) {
            saveAccountOrganizationProjectIds(projectIds, accountId);
            saveAccountProject(projectIds, accountId);
        }
    }

    @Override
    public ResultJson addRole(Integer accountId, List<Integer> roleIds) {

        Account account = accountDao.selectById(accountId);
        if(null == account){
            return ResultJson.fail("帐号不存在");
        }
        RoleQuery roleQuery = new RoleQuery();
        roleQuery.setIdList(roleIds);
        List<Role> roleList = roleService.getRoleList(null, roleQuery);
        if(CollectionUtils.isEmpty(roleList)){
            return ResultJson.fail("角色不存在");
        }
        List<Integer> roles = roleList.stream().map(i -> i.getId()).collect(Collectors.toList());

        QueryWrapper<AccountRole> accountRoleQueryWrapper = new QueryWrapper<>();
        accountRoleQueryWrapper.eq("account_id", accountId);
        List<AccountRole> accountRoles = accountRoleDao.selectList(accountRoleQueryWrapper);
        // 去重，防止重复关联角色
        if(!CollectionUtils.isEmpty(accountRoles)){
            List<Integer> collect = accountRoles.stream().map(i -> i.getRoleId()).collect(Collectors.toList());
            roles.removeAll(collect);
        }
        if(!CollectionUtils.isEmpty(roles)){
            // 添加帐号和角色的关联关系
            List<AccountRole> accountRoles1 = new ArrayList<>();
            for (Integer role : roles) {
                AccountRole accountRole = new AccountRole();
                accountRole.setRoleId(role);
                accountRole.setAccountId(accountId);
                accountRoles1.add(accountRole);
            }
            accountRoleService.saveBatch(accountRoles1);
            // 添加权限组
            PermissionGroup permissionGroup = new PermissionGroup();
            permissionGroup.setAccountId(accountId);
            permissionGroup.setRoleIds(Joiner.on(",").join(roles));
            permissionGroupService.save(permissionGroup);
        }
        return ResultJson.success();
    }

    @Override
    public ResultJson removeRole(Integer accountId, List<Integer> roleIds) {
        if(CollectionUtils.isEmpty(roleIds)){
            log.info("需要移除的角色为空");
            return ResultJson.success();
        }

        // 移除帐号角色关系
        UpdateWrapper<AccountRole> accountRoleUpdateWrapper = new UpdateWrapper<>();
        accountRoleUpdateWrapper.eq("account_id", accountId);
        accountRoleUpdateWrapper.in("role_id", roleIds);
        accountRoleService.remove(accountRoleUpdateWrapper);

        // 移除权限组
        QueryWrapper<PermissionGroup> permissionGroupQueryWrapper = new QueryWrapper<>();
        permissionGroupQueryWrapper.eq("account_id", accountId);
        List<PermissionGroup> list = permissionGroupService.list(permissionGroupQueryWrapper);
        if(CollectionUtils.isEmpty(list)){
            log.info("帐号 {} 没有权限组信息", accountId);
            return ResultJson.success();
        }

        List<PermissionGroup> updateList = new ArrayList<>();
        for (PermissionGroup permissionGroup : list) {
            List<String> strings = Arrays.asList(permissionGroup.getRoleIds().split(","));
            List<Integer> groupRoleIds = strings.stream().map(i -> Integer.valueOf(i)).collect(Collectors.toList());
            List<Integer> groupRoleIdsOld = new ArrayList<>();
            groupRoleIdsOld.addAll(groupRoleIds);
            groupRoleIds.retainAll(roleIds);
            if(CollectionUtils.isEmpty(groupRoleIds)){
                continue;
            }else{
                groupRoleIdsOld.removeAll(groupRoleIds);
                if(CollectionUtils.isEmpty(groupRoleIdsOld)){
                    permissionGroupService.removeById(permissionGroup.getId());
                    continue;
                }
                permissionGroup.setRoleIds(Joiner.on(",").join(groupRoleIdsOld));
                updateList.add(permissionGroup);
            }
        }
        permissionGroupService.saveOrUpdateBatch(updateList);
        return null;
    }


    /**
     * 获取某个账号的 内置角色数据关系
     *
     * @param id
     * @return
     */
    @Override
    public ResultJson getAccountCommonInitRoles(Integer id) {
        if (null == id) {
            return ResultJson.fail("缺少账号信息");
        }
        AccountInitRoleRelDTO accountInitRoleRelDTO = (AccountInitRoleRelDTO) redisUtils.get(id + "_INIT_ROLE");
        return ResultJson.success(accountInitRoleRelDTO);
    }

    @Override
    public ResultJson isAdminCheck(Integer id, Integer projectId) {

        Project project = projectService.findById(projectId);
        if (null == project) {
            return ResultJson.fail("项目不存在");
        }
        List<Integer> roleIds = accountRoleService.findRoleIdByAccountId(id);
        if (CollectionUtils.isEmpty(roleIds)) {
            return ResultJson.fail("账号数据异常");
        }
        Integer enterpriseId = project.getEnterpriseId();
        Short industryId = project.getIndustryId();
        //当前业态超管
        QueryWrapper<Role> superRoleQueryWrapper = new QueryWrapper<>();
        superRoleQueryWrapper.eq("industry_id", industryId);
        superRoleQueryWrapper.eq("type", RoleTypeEnum.SUPPER_MANAGER.getCode());
        superRoleQueryWrapper.eq("grade", BusinessType.INDUSTRY.getCode());
        Role superAdminRole = roleDao.selectOne(superRoleQueryWrapper);
        if (null != superAdminRole) {
            Integer superAdminRoleId = superAdminRole.getId();
            if (roleIds.contains(superAdminRoleId)) {
                return ResultJson.success(true);
            }
        }
        //当前项目的企业-企业管理员
        QueryWrapper<Role> entRoleQueryWrapper = new QueryWrapper<>();
        entRoleQueryWrapper.eq("enterprise_id", enterpriseId);
        entRoleQueryWrapper.eq("type", RoleTypeEnum.MANAGER.getCode());
        entRoleQueryWrapper.eq("grade", BusinessType.ENTERPRISE.getCode());
        Role entAdminRole = roleDao.selectOne(entRoleQueryWrapper);
        if (null != entAdminRole) {
            Integer entAdminRoleId = entAdminRole.getId();
            if (roleIds.contains(entAdminRoleId)) {
                return ResultJson.success(true);
            }
        }
        //当前项目-项目管理员
        QueryWrapper<Role> proRoleQueryWrapper = new QueryWrapper<>();
        proRoleQueryWrapper.eq("project_id", projectId);
        proRoleQueryWrapper.eq("type", RoleTypeEnum.MANAGER.getCode());
        proRoleQueryWrapper.eq("grade", BusinessType.PROJECT.getCode());
        Role projectAdminRole = roleDao.selectOne(proRoleQueryWrapper);
        if (null != projectAdminRole) {
            Integer projectAdminRoleId = projectAdminRole.getId();
            if (roleIds.contains(projectAdminRoleId)) {
                return ResultJson.success(true);
            }
        }
        return ResultJson.success(false);
    }


    /**
     * 创建游客
     *
     * @param account
     * @return
     */
    @Override
    public ResultJson generateVisitor(Account account, List<Integer> projectIds) {
        Short industryId = account.getIndustryId();
        if (industryId == null) {
            throw new BusinessException("游客角色绑定平台，需传industryId参数");
        }
        List<Role> roleList = roleService.getTouristRoleByIndustryId(industryId);
        if (CollectionUtils.isEmpty(roleList)) {
            throw new BusinessException("当前平台，没有游客类型角色");
        }
        Role role = roleList.get(0);
        List<Integer> roleIds = Collections.singletonList(role.getId());
        //设置初始密码
        if (StringUtils.isEmpty(account.getPassword())) {
            account.setPassword(DEFAULT_PWD);
        }
        //插入账号信息
        accountDataVerify(account);
        //业态下，手机号 唯一 / 账号 唯一
        accountUnique(account);
        //密码加密
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String pwdEncode = bCryptPasswordEncoder.encode(account.getPassword());
        account.setPassword(pwdEncode);
        if (null == account.getType()) {
            account.setType((short) 1);
        }
        if (null == account.getCertification()) {
            account.setCertification(false);
        }
        accountDao.insert(account);
        //人员角色表
        if (!CollectionUtils.isEmpty(roleIds)) {
            //先删除
            QueryWrapper<AccountRole> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("account_id", account.getId());
            accountRoleService.remove(queryWrapper);
            List<AccountRole> accountRoleList = new ArrayList<>();
            for (Integer roleId : roleIds) {
                AccountRole accountRole = new AccountRole();
                accountRole.setAccountId(account.getId());
                accountRole.setRoleId(roleId);
                accountRoleList.add(accountRole);
            }
            accountRoleService.saveBatch(accountRoleList);
        }
        //如果项目列表不为空，加上项目的权限
        if (!CollectionUtils.isEmpty(projectIds)) {
            addProjectToAccount(account.getId(), roleIds, projectIds);
        }
        return ResultJson.success("操作成功", account.getId());
    }


    /**
     * 批量新增账号 & 关联数据
     *
     * @param accountList
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultJson<Map<String, Integer>> createAccountBatch(List<AccountBatchDTO> accountList) {
        Map<String, Integer> map = new HashMap<>();
        for (AccountBatchDTO accountDTO : accountList) {
            Account account = accountDTO.getAccount();
            List<Integer> enterpriseIds = accountDTO.getEnterpriseIds();
            List<Integer> projectIds = accountDTO.getProjectIds();
            List<Integer> roleIds = accountDTO.getRoleIds();
            ResultJson saveResult = createAccount(account, enterpriseIds, projectIds, roleIds);
            if (!CodeEnum.SUCCESS.getCode().equals(saveResult.getCode())) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                throw new DataException("批量新增账号异常，事务已回滚");
            }
            map.put(account.getLoginName(), Integer.valueOf(String.valueOf(saveResult.getResult())));
        }
        return ResultJson.success("操作成功", map);
    }


    /**
     * 新增账号关联数据
     *
     * @param accountId
     * @param enterpriseIds
     * @param projectIds
     * @param roleIds
     */
    public void accountRelationUpdate(Integer accountId, List<Integer> enterpriseIds, List<Integer> projectIds, List<Integer> roleIds) {
        //人员组织(企业)表
        if (!CollectionUtils.isEmpty(enterpriseIds)) {
            //先删除
            QueryWrapper<AccountOrganization> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("account_id", accountId);
            queryWrapper.in("type", Arrays.asList(OrganizationTypeEnum.PROJECT.id, OrganizationTypeEnum.ENTERPRISE.id));
            accountOrganizationService.remove(queryWrapper);
            //再新增
            QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
            //维护组织表数据，每个项目所属的企业id，对应的组织数据都需要插入
            if (!CollectionUtils.isEmpty(projectIds)) {
                projectQueryWrapper.in("id", projectIds);
                List<Project> projectsList = projectDao.selectList(projectQueryWrapper);
                saveAccountOrganizationProject(projectsList, accountId);
            }
            if (!CollectionUtils.isEmpty(enterpriseIds)) {
                QueryWrapper<Enterprise> enterpriseQueryWrapper = new QueryWrapper<>();
                enterpriseQueryWrapper.in("id", enterpriseIds);
                List<Enterprise> enterpriseList = enterpriseDao.selectList(enterpriseQueryWrapper);
                saveAccountOrganizationEnterprise(enterpriseList, accountId);
            }

        }
        //人员项目关系表
        if (!CollectionUtils.isEmpty(projectIds)) {
            //先删除
            QueryWrapper<AccountProject> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("account_id", accountId);
            accountProjectService.remove(queryWrapper);
            //再更新
            List<AccountProject> accountProjectList = new ArrayList<>(projectIds.size());
            for (Integer projectId : projectIds) {
                AccountProject accountProject = new AccountProject();
                accountProject.setAccountId(accountId);
                accountProject.setProjectId(projectId);
                accountProjectList.add(accountProject);
            }
            accountProjectService.saveBatch(accountProjectList);
        }
        //人员角色表
        if (!CollectionUtils.isEmpty(roleIds)) {
            //先删除
            QueryWrapper<AccountRole> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("account_id", accountId);
            accountRoleService.remove(queryWrapper);
            List<AccountRole> accountRoleList = new ArrayList<>();
            for (Integer roleId : roleIds) {
                AccountRole accountRole = new AccountRole();
                accountRole.setAccountId(accountId);
                accountRole.setRoleId(roleId);
                accountRoleList.add(accountRole);
            }
            accountRoleService.saveBatch(accountRoleList);
        }


    }


    /**
     * 账号修改
     * 注意点：账号信息里边包含了业态id,以后如果需要扩展可以是要业态id做逻辑的扩展
     *
     * @param operateAccount
     * @param account
     * @param enterpriseIds
     * @param projectIds
     * @param roleIds
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultJson updateAccount(Account operateAccount, Account account, List<Integer> enterpriseIds, List<Integer> projectIds, List<Integer> roleIds) {
        updateAccountOrigin(operateAccount, account, enterpriseIds, projectIds, roleIds);
        // 更新权限组
        updatePermissionGroup(roleIds, projectIds, account.getId());
        updateSendToMQ(account, account.getPassword());
        return ResultJson.success("操作成功");
    }

    /**
     * 校验 operateAccount 是否能够修改 account
     *
     * @param operateAccount
     * @param account
     */
    private void updateAccountCheck(AbstractAccount operateAccount, Account account) {
        //获取当前登录操作账号的角色身份
        RoleTypeEnum operateRoleType = roleService.getAccountRoleType(operateAccount.getId()).getRoleTypeEnum();
        //查出需要修改的账号的角色身份
        RoleTypeEnum updateAccountRoleType = roleService.getAccountRoleType(account.getId()).getRoleTypeEnum();
        Boolean checkResult = updateAccountCheck(account.getIndustryId(), operateRoleType, updateAccountRoleType);
        if (!checkResult) {
            throw new BusinessException("修改失败,权限不足");
        }
    }

    /**
     * 账号更新消息推送至mq
     *
     * @param account
     * @param originalPassword
     */
    private void updateSendToMQ(Account account, String originalPassword) {
        //推送到Kafka账号更新主题
        AccountDTO pushAccount = new AccountDTO();
        try {
            AccountQuery accountQuery = new AccountQuery();
            accountQuery.setIdList(Arrays.asList(account.getId()));
            List<AccountDTO> list = getList(accountQuery);
            if (!CollectionUtils.isEmpty(list)) {
                pushAccount = list.get(0);
                if (StringUtils.isNotEmpty(originalPassword)) {
                    pushAccount.setPassword(originalPassword);
                }
                pushAccount.setIdCard(account.getIdCard());
                // 将记录原loginName进行推送
                pushAccount.setLastLoginName(account.getLastLoginName());
                accountProducer.updatePush(JSON.toJSONString(pushAccount));
            }
        } catch (Exception e) {
            log.info("当前账号数据推送到更新主题异常,账号数据={}", pushAccount.toString());
        }
    }

    /**
     * 更新账号
     *
     * @param operateAccount
     * @param account
     * @param enterpriseIds
     * @param projectIds
     * @param roleIds
     */
    private void updateAccountOrigin(Account operateAccount, Account account, List<Integer> enterpriseIds, List<Integer> projectIds, List<Integer> roleIds) {
        if (Objects.isNull(account.getId())) {
            throw new DataException("缺少账号数据");
        }
        //角色ID去重,有可能前端传入重复参数
        if (ChkUtil.isNotNull(roleIds)) {
            roleIds = roleIds.stream().distinct().collect(Collectors.toList());
        }
//        updateAccountCheck(operateAccount, account);
        //手机号校验
        //不允许 空格串和空数据
        if (StringUtils.isNotEmpty(account.getPhone())) {
            CentDataVerifyUtil.phoneVerify(account.getPhone());
        }
        //账号登录名不允许包含空格
        if (StringUtils.isNotEmpty(account.getLoginName())) {
            CentDataVerifyUtil.loginNameVerify(account.getLoginName());
        }
        if (StringUtils.isNotEmpty(account.getLoginName()) && StringUtils.isNotEmpty(account.getPassword())) {
            if (account.getLoginName().equals(account.getPassword())) {
                throw new DataException("用户名与密码不能相同");
            }
        }
        String originalPassword = "";
        if (StringUtils.isNotEmpty(account.getPassword())) {
            //密码加密
            originalPassword = account.getPassword();
            CentDataVerifyUtil.pwdVerify(originalPassword);

            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            String pwdEncode = bCryptPasswordEncoder.encode(originalPassword);
            account.setPassword(pwdEncode);
        }

        Account accountExist = accountDao.selectById(account.getId());
        if (Objects.isNull(accountExist)) {
            log.info("检测到账号数据不存在，id={}", account.getId());
            throw new DataException("账号数据不存在");
        }
        // 如果没有设置密码 则获取之前的旧密码
        if(StringUtils.isEmpty(account.getPassword())){
            account.setPassword(accountExist.getPassword());
        }
        account.setDevelopId(accountExist.getDevelopId());
        //业态下 账号唯一、手机号、邮箱 唯一验重
        accountUnique(account);
        //根据角色反查项目ids 和企业ids
        Map<String, List<Integer>> entAndProIdMap = convertEntAndProIdMap(account, enterpriseIds, projectIds, roleIds);
        List<Integer> resultEntIdList = entAndProIdMap.get("entIdList");
        List<Integer> resultProIdList = entAndProIdMap.get("proIdList");
        Integer accountId = account.getId();
        // 记录原loginName
        account.setLastLoginName(accountExist.getLoginName());

        try {
            if (StringUtils.isNotEmpty(account.getName())) {
                String nameCovert = EmojiParser.parseToAliases(account.getName());
                account.setName(nameCovert);
            }
            if (StringUtils.isNotEmpty(account.getNickname())) {
                String nickNameCovert = EmojiParser.parseToAliases(account.getNickname());
                account.setNickname(nickNameCovert);
            }
            int effectNumUpdate = accountDao.updateById(account);
            if (effectNumUpdate != 1) {
                throw new DataException("更新账号数据失败");
            }

            // 更新员工信息表
            UpdateWrapper<Staff> staffUpdateWrapper = new UpdateWrapper<>();
            staffUpdateWrapper.set("name", account.getName());
            staffUpdateWrapper.eq("account_id", account.getId());
            staffService.update(staffUpdateWrapper);

            //删除 账号-组织关联表
            QueryWrapper<AccountOrganization> orgQueryWrapper = new QueryWrapper<>();
            orgQueryWrapper.eq("account_id", accountId);
            orgQueryWrapper.in("type", Arrays.asList(OrganizationTypeEnum.ENTERPRISE.id, OrganizationTypeEnum.PROJECT.id));
            // 只影响当前企业的信息
            if (!CollectionUtils.isEmpty(enterpriseIds)) {
                orgQueryWrapper.in("enterprise_id", enterpriseIds);
            }
            accountOrganizationService.remove(orgQueryWrapper);
            //新增 账号-组织关联表
            if (!CollectionUtils.isEmpty(resultProIdList)) {
                QueryWrapper<Project> proQueryWrapper = new QueryWrapper<>();
                proQueryWrapper.in("id", resultProIdList);
                List<Project> proList = projectDao.selectList(proQueryWrapper);
                saveAccountOrganizationProject(proList, accountId);
            } else if (!CollectionUtils.isEmpty(resultEntIdList)) {
                QueryWrapper<Enterprise> entQueryWrapper = new QueryWrapper<>();
                entQueryWrapper.in("id", resultEntIdList);
                List<Enterprise> entList = enterpriseDao.selectList(entQueryWrapper);
                saveAccountOrganizationEnterprise(entList, accountId);
            }
            //删除 账号-项目关联表
            QueryWrapper<AccountProject> accountProjectQueryWrapper = new QueryWrapper<>();
            accountProjectQueryWrapper.eq("account_id", accountId);
            // 只能操作当前企业下的
            if(!CollectionUtils.isEmpty(enterpriseIds)){
                //是否是运营商
                QueryWrapper<Enterprise> entQueryWrapper = new QueryWrapper<>();
                entQueryWrapper.in("id", resultEntIdList);
                List<Enterprise> ents = enterpriseDao.selectList(entQueryWrapper);
                boolean flag = false;
                for(Enterprise vo:ents){
                    if(vo.getType().contains("1")){
                        flag = true;
                        break;
                    }
                }
                List<Integer> projectIdLists = null;
                if(flag) {
                    //运营上
                    QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
                    projectQueryWrapper.select("id");
                    projectQueryWrapper.in("enterprise_id", enterpriseIds);
                    projectQueryWrapper.eq("is_deleted", false);
                    List<Project> projects = projectDao.selectList(projectQueryWrapper);
                    if(!CollectionUtils.isEmpty(projects)) {
                        projectIdLists = projects.stream().map(i -> i.getId()).collect(Collectors.toList());
                    }
                }else {
                    //入驻企业
                    QueryWrapper<EnterpriseProject> enterpriseProjectQueryWrapper = new QueryWrapper<>();
                    enterpriseProjectQueryWrapper.in("enterprise_id", enterpriseIds);
                    List<EnterpriseProject> enterpriseProjects = enterpriseProjectService.list(enterpriseProjectQueryWrapper);
                    if(!CollectionUtils.isEmpty(enterpriseProjects)) {
                        projectIdLists = enterpriseProjects.stream().map(i -> i.getProjectId()).collect(Collectors.toList());
                    }
                }
                if(!CollectionUtils.isEmpty(projectIdLists)){
                    accountProjectQueryWrapper.in("project_id", projectIdLists);
                    accountProjectService.remove(accountProjectQueryWrapper);
                }
            }
            //新增 账号-项目关联表
            if (!CollectionUtils.isEmpty(resultProIdList)) {
                accountProjectService.insert(accountId, resultProIdList);
            }
            RoleQuery roleQuery = new RoleQuery();
            // 只删除当前企业的角色 其他的不影响
            List<Integer> notRemoveId = new ArrayList<>();
            if(!CollectionUtils.isEmpty(enterpriseIds)){
                roleQuery.setEnterpriseIdList(enterpriseIds);
                //查找非当前企业的权限组
                QueryWrapper<PermissionGroup> permissionGroupQueryWrapper = new QueryWrapper<>();
                permissionGroupQueryWrapper.eq("account_id",accountId);
                permissionGroupQueryWrapper.and(i -> i.ne("enterprise_id",enterpriseIds.get(0)).or().isNull("enterprise_id"));
                List<PermissionGroup> permissionGroups = permissionGroupService.list(permissionGroupQueryWrapper);

                if (null != permissionGroups && !permissionGroups.isEmpty()){
                    for (PermissionGroup p : permissionGroups){
                        if (null != p.getRoleIds() && StringUtils.isNotEmpty(p.getRoleIds())){
                            notRemoveId.addAll(Arrays.stream(p.getRoleIds().split(",")).map(Integer::valueOf).collect(Collectors.toList()));
                        }
                    }
                }
            }
            //删除操作人 可以的管理角色
            List<Role> roleList = roleService.getRoleList(operateAccount, roleQuery);
            if (!CollectionUtils.isEmpty(roleList)) {
                List<Integer> roleIdList = roleList.stream().filter(i -> !notRemoveId.contains(i.getId())).map(Role::getId).collect(Collectors.toList());
                accountRoleService.deleteAccountRole(Arrays.asList(accountId), roleIdList);
            }
            // 删除业态角色
            RoleQuery roleQuery2 = new RoleQuery();
            // 查询业态角色
            roleQuery2.setGrade((short) 2);
            List<Role> industryRoles = roleService.getRoleList(operateAccount, roleQuery2);
            if(!CollectionUtils.isEmpty(industryRoles)){
                accountRoleService.deleteAccountRole(Arrays.asList(accountId), industryRoles.stream().filter(i -> !notRemoveId.contains(i.getId())).map(i -> i.getId()).collect(Collectors.toList()));
            }

            //新增账号-角色
            accountRoleService.insertAccountRole(accountId, roleIds);
        } catch (Exception e) {
            e.printStackTrace();
            throw new DataException("更新账号数据失败" + e.getMessage());
        }
        //维护  账号、 业态角色 、 项目 之间的关系
        holdAccountInitRole(account, projectIds, roleIds, OperationTypeEnum.UPDATE.getType());
        Account accountDb = findById(account.getId());
        //记录操作日志
        accountLogRecord(operateAccount, LogOperationTypeEnum.UPDATE, "编辑账号" + "【" + accountDb.getLoginName() + "】");
    }

    @Override
    @Transactional
    public ResultJson updateAccountV2(Account operateAccount, Account account, AccountRelation accountRelation, List<PermissionGroupDTO> permissionGroupDTOList) {
        if(null == accountRelation  || null == accountRelation.getCurrentIndustryId()){
            log.error("缺少当前操作的业态信息");
            return ResultJson.fail("缺少当前操作的业态信息");
        }
        updateAccountOrigin(operateAccount, account, null == accountRelation ? null : accountRelation.getEnterpriseIds(),
                null == accountRelation ? null : accountRelation.getProjectIds(),
                null == accountRelation ? null : accountRelation.getRoleIds());
        // 更新权限组
//        savePermissionGroupV2(operateAccount, account.getId(), permissionGroupDTOList, accountRelation);
        savePermissionGroupV3(account.getId(),permissionGroupDTOList);
        updateSendToMQ(account, account.getPassword());
        return ResultJson.success("操作成功");
    }

    /**
     * accountRelation企业信息不为空的时候 只更新当前企业的权限组
     * 可以代替 savePermissionGroup 使用
     * @param accountId
     * @param permissionGroupDTOList
     * @param accountRelation
     */
    private void savePermissionGroupV2(Account operateAccount, Integer accountId, List<PermissionGroupDTO> permissionGroupDTOList, AccountRelation accountRelation){

        if(null != accountRelation && !CollectionUtils.isEmpty(accountRelation.getEnterpriseIds())){
            // 只删除当前企业的权限组
            RoleQuery roleQuery = new RoleQuery();
            roleQuery.setEnterpriseIdList(accountRelation.getEnterpriseIds());
            //删除操作人 可以的管理角色 (与 account_role 修改一致)
            List<Role> roleList = roleService.getRoleList(operateAccount, roleQuery);
            List<Integer> roleIds = roleList.stream().map(i -> i.getId()).collect(Collectors.toList());

            // 查询当前业态的角色
            RoleQuery roleQuery1 = new RoleQuery();
            roleQuery1.setIndustryIdList(Arrays.asList(accountRelation.getCurrentIndustryId().shortValue()));
            roleQuery1.setGrade((short) 2);
            List<Role> industryRoles = roleService.getRoleList(null, roleQuery1);
            List<Integer> industryRoleIds = new ArrayList<>();
            industryRoleIds = industryRoles.stream().map(i -> i.getId()).collect(Collectors.toList());

            QueryWrapper<PermissionGroup> permissionGroupQueryWrapper = new QueryWrapper<>();
            permissionGroupQueryWrapper.eq("account_id", accountId);
            List<PermissionGroup> permissionGroups = permissionGroupService.list(permissionGroupQueryWrapper);
            List<Integer> permissionGroupIdsDeleted = new ArrayList<>();
            for (PermissionGroup permissionGroup : permissionGroups) {
                List<Integer> collect = Arrays.asList(permissionGroup.getRoleIds().split(",")).stream().map(i -> Integer.valueOf(i)).collect(Collectors.toList());
                for (Integer integer : collect) {
                    // 包含当前所在当前企业的角色就删除该权限组 or 包含当前业态的业态角色
                    if(roleIds.contains(integer) || industryRoleIds.contains(integer)){
                        permissionGroupIdsDeleted.add(permissionGroup.getId());
                        break;
                    }
                }
            }
            if(!CollectionUtils.isEmpty(permissionGroupIdsDeleted)){
                permissionGroupService.removeByIds(permissionGroupIdsDeleted);
            }
            createPermissionGroup(accountId, permissionGroupDTOList);
        }else{
            savePermissionGroup(accountId, permissionGroupDTOList);
        }
    }

    /**
     * 权限组根据企业更新 进更新当前企业的权限组
     * 可以代替 savePermissionGroupV2 使用
     * @param accountId
     * @param permissionGroupDTOList
     */
    private void savePermissionGroupV3(Integer accountId, List<PermissionGroupDTO> permissionGroupDTOList){
        // 先删除当前企业的权限组 后新增
        QueryWrapper<PermissionGroup> permissionGroupQueryWrapper = new QueryWrapper<>();
        permissionGroupQueryWrapper.eq("account_id", accountId);
        permissionGroupQueryWrapper.eq("enterprise_id",permissionGroupDTOList.get(0).getEnterpriseId());
        permissionGroupService.remove(permissionGroupQueryWrapper);
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(permissionGroupDTOList)) {
            log.warn("该账号 {} 没有权限信息");
            return;
        }
        createPermissionGroup(accountId, permissionGroupDTOList);
    }


        public boolean crossEnterpriseVerify(List<Integer> resultEntIdList, Integer accountId) {
        List<AccountOrganization> accountOrganizations = accountOrganizationService.findByAccountId(accountId);
        Set<Integer> entIdsDb = new HashSet<>();
        if (!CollectionUtils.isEmpty(accountOrganizations)) {
            for (AccountOrganization accountOrganization : accountOrganizations) {
                entIdsDb.add(accountOrganization.getEnterpriseId());
            }
            if (!CollectionUtils.isEmpty(resultEntIdList)) {
                for (Integer needAddEntId : resultEntIdList) {
                    if (!entIdsDb.contains(needAddEntId)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 维护账号的普通内置角色、项目的管理关系
     *
     * @param account
     * @param projectIds
     * @param roleIds
     */
    public void holdAccountInitRole(Account account, List<Integer> projectIds, List<Integer> roleIds, Short operationType) {
        try {
            Short industryId = account.getIndustryId();
            Integer needHoldAccountId = account.getId();
            List<Integer> commonInitializedRoles = roleService.getCommonInitializedRoles(Arrays.asList(industryId));
            List<Integer> needUpholdRelationCommonRoles = new ArrayList<>();
            if (!CollectionUtils.isEmpty(roleIds) && !CollectionUtils.isEmpty(commonInitializedRoles)) {
                for (Integer roleId : roleIds) {
                    if (commonInitializedRoles.contains(roleId)) {
                        needUpholdRelationCommonRoles.add(roleId);
                    }
                }
            }
            List<ProInitRoleRelDTO> proInitRoles = new ArrayList<>();
            if (!CollectionUtils.isEmpty(projectIds) && !CollectionUtils.isEmpty(needUpholdRelationCommonRoles)) {
                //修改
                if (operationType.equals(OperationTypeEnum.UPDATE.getType())) {
                    AccountInitRoleRelDTO accountInitRoleRelDTO = (AccountInitRoleRelDTO) redisUtils.get(needHoldAccountId + "_" + "" + "INIT_ROLE");
                    if (null == accountInitRoleRelDTO) {
                        accountInitRoleRelDTO = new AccountInitRoleRelDTO();
                        for (Integer proId : projectIds) {
                            ProInitRoleRelDTO proInitRoleRelDTO = new ProInitRoleRelDTO();
                            proInitRoleRelDTO.setProjectId(proId);
                            proInitRoleRelDTO.setRoleIds(needUpholdRelationCommonRoles);
                            proInitRoles.add(proInitRoleRelDTO);
                        }
                        accountInitRoleRelDTO.setId(needHoldAccountId);
                        accountInitRoleRelDTO.setProInitRoles(proInitRoles);
                        redisUtils.set(needHoldAccountId + "_" + "" + "INIT_ROLE", accountInitRoleRelDTO);
                    } else {
                        List<ProInitRoleRelDTO> proInitRoleList = accountInitRoleRelDTO.getProInitRoles();
                        for (Integer proId : projectIds) {
                            for (ProInitRoleRelDTO roleRelDTO : proInitRoleList) {
                                if (roleRelDTO.getProjectId().equals(proId)) {
                                    roleRelDTO.setRoleIds(needUpholdRelationCommonRoles);
                                }
                            }
                        }
                    }
                    //新增
                } else if (operationType.equals(OperationTypeEnum.CREATE.getType())) {
                    AccountInitRoleRelDTO accountInitRoleRelDTO = new AccountInitRoleRelDTO();
                    redisUtils.remove(needHoldAccountId + "_" + "" + "INIT_ROLE");
                    for (Integer proId : projectIds) {
                        ProInitRoleRelDTO proInitRoleRelDTO = new ProInitRoleRelDTO();
                        proInitRoleRelDTO.setProjectId(proId);
                        proInitRoleRelDTO.setRoleIds(needUpholdRelationCommonRoles);
                        proInitRoles.add(proInitRoleRelDTO);
                    }
                    accountInitRoleRelDTO.setId(needHoldAccountId);
                    accountInitRoleRelDTO.setProInitRoles(proInitRoles);
                    redisUtils.set(needHoldAccountId + "_" + "" + "INIT_ROLE", accountInitRoleRelDTO);
                    //删除
                } else if (operationType.equals(OperationTypeEnum.DELETE.getType())) {
                    AccountInitRoleRelDTO accountInitRoleRelDTO = (AccountInitRoleRelDTO) redisUtils.get(needHoldAccountId + "_" + "" + "INIT_ROLE");
                    if (null != accountInitRoleRelDTO) {
                        List<ProInitRoleRelDTO> proInitRoleList = accountInitRoleRelDTO.getProInitRoles();
                        for (Integer proId : projectIds) {
                            for (ProInitRoleRelDTO roleRelDTO : proInitRoleList) {
                                if (roleRelDTO.getProjectId().equals(proId)) {
                                    List<Integer> roleIdsDb = roleRelDTO.getRoleIds();
                                    HashSet<Integer> roleIdsDbSet = new HashSet<>(roleIdsDb);
                                    HashSet<Integer> needUpholdRelationCommonRolesSet = new HashSet<>(needUpholdRelationCommonRoles);
                                    roleIdsDbSet.removeAll(needUpholdRelationCommonRolesSet);
                                    List<Integer> roleIdsDbResult = new ArrayList<>(roleIdsDbSet);
                                    if (CollectionUtils.isEmpty(roleIdsDbResult)) {
                                        proInitRoleList.remove(roleRelDTO);
                                    } else {
                                        roleRelDTO.setRoleIds(roleIdsDbResult);
                                    }
                                }
                            }
                        }
                        if (CollectionUtils.isEmpty(proInitRoleList)) {
                            redisUtils.remove(needHoldAccountId + "_" + "" + "INIT_ROLE");
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.info("redis维护账号特殊身份数据异常，不影响主流程，暂时记录一下");
        }

    }


    /**
     * 根据loginName查找账号
     *
     * @param loginName
     * @param industryId
     * @return
     */
    @Override
    public Account findByLoginName(String loginName, Short industryId) {
        if (StringUtils.isEmpty(loginName)) {
            throw new DataException("登录名不能为空");
        }
        AccountQuery accountQuery = new AccountQuery();
        accountQuery.setLoginName(loginName);
        if (null != industryId) {
            accountQuery.setIndustryId(industryId);
        }
        List<Account> accountList = accountDao.selectList(handleParams(accountQuery));
        if (CollectionUtils.isEmpty(accountList)) {
            return null;
        }
        return accountList.get(0);
    }

    /**
     * 根据loginName查找账号V2
     * @param loginName
     * @param developId
     * @return
     */
    @Override
    public Account findByLoginNameV2(String loginName, Integer developId) {
        if (StringUtils.isEmpty(loginName)) {
            throw new DataException("登录名不能为空");
        }
        AccountQuery accountQuery = new AccountQuery();
        accountQuery.setLoginName(loginName);
        if (null != developId) {
            accountQuery.setDevelopId(developId);
        }
        List<Account> accounts = accountDao.selectList(handleParams(accountQuery));
        if (CollectionUtils.isEmpty(accounts)) {
            return null;
        }
        return accounts.get(0);
    }

    /**
     * 根据账号id 查找角色、组织相关信息
     *
     * @param id
     * @return
     */
    @Override
    public List<AccountRolesDTO> getAccountRoles(Integer id) {
        if (Objects.isNull(id)) {
            throw new DataException("缺少账号数据");
        }
        List<AccountRolesDTO> accountRolesDTOList = new ArrayList<>();
        List<Integer> roleIds = accountRoleService.findRoleIdByAccountId(id);
        RoleQuery roleQuery = new RoleQuery();
        roleQuery.setIdList(roleIds);
        List<Role> roleList = roleService.getRoleList(null, roleQuery);
        if (CollectionUtils.isEmpty(roleList)) {
            return Collections.emptyList();
        }
        //当前的角色ids 的企业id集合
        HashSet<Integer> entIdSet = new HashSet<>();
        for (Role role : roleList) {
            if (null != role.getEnterpriseId()) {
                entIdSet.add(role.getEnterpriseId());
            }
        }
        //当前的角色ids 的项目id集合
        HashSet<Integer> proIdSet = new HashSet<>();
        for (Role role : roleList) {
            if (null != role.getProjectId()) {
                proIdSet.add(role.getProjectId());
            }
        }
        if (CollectionUtils.isEmpty(entIdSet) && CollectionUtils.isEmpty(proIdSet)) {
            for (Role role : roleList) {
                AccountRolesDTO accountRolesDTO = new AccountRolesDTO();
                accountRolesDTO.setId(id);
                accountRolesDTO.setRoleId(role.getId());
                accountRolesDTO.setRoleName(role.getName());
                accountRolesDTOList.add(accountRolesDTO);
            }
            return accountRolesDTOList;
        }
        List<Integer> entIdList = new ArrayList<>(entIdSet);
        List<Integer> proIdList = new ArrayList<>(proIdSet);
        //项目id集合
        ProjectQuery projectQuery = new ProjectQuery();
        projectQuery.withIdList(proIdList);
        List<Project> projects = projectService.list(projectQuery, null);
        Map<Integer, String> projectNameMap = projects.stream().collect(Collectors.toMap(Project::getId, Project::getName));

        //处理项目的组织id集合
        OrganizationQuery projectOrganizationQuery = new OrganizationQuery();
        projectOrganizationQuery.withProjectIds(proIdList);
        projectOrganizationQuery.withTypes(Arrays.asList(OrganizationTypeEnum.PROJECT.id.intValue()));
        List<Organization> projectOrganizations = organizationService.list(projectOrganizationQuery);
        if (CollectionUtils.isEmpty(projectOrganizations)) {
            log.warn("当前需要查找的项目集合为={}，但是获取不到相关的组织数据", proIdList.toString());
            throw new DataException("项目集合无对应组织数据");
        }

        Map<Integer, Integer> projectOrganizationMap = projectOrganizations.stream().collect(Collectors.toMap(Organization::getProjectId, Organization::getId));
        List<Integer> projectOrganizationIdList = projectOrganizations.stream().map(Organization::getId).collect(Collectors.toList());
        //处理企业的组织id集合
        OrganizationQuery enterpriseOrganizationQuery = new OrganizationQuery();
        enterpriseOrganizationQuery.withEnterpriseIds(entIdList);
        enterpriseOrganizationQuery.withTypes(Arrays.asList(OrganizationTypeEnum.ENTERPRISE.id.intValue()));
        List<Organization> enterpriseOrganizations = organizationService.list(enterpriseOrganizationQuery);
        if (CollectionUtils.isEmpty(enterpriseOrganizations)) {
            log.warn("当前需要查找的企业集合为={}，但是获取不到相关的组织数据", entIdList.toString());
            throw new DataException("企业集合无对应组织数据");
        }
        Map<Integer, Integer> enterpriseOrganizationMap = enterpriseOrganizations.stream().collect(Collectors.toMap(Organization::getEnterpriseId, Organization::getId));
        List<Integer> enterpriseOrganizationIdList = enterpriseOrganizations.stream().map(e -> e.getId()).collect(Collectors.toList());
        List<Integer> organizationIdAll = new ArrayList<>();
        organizationIdAll.addAll(projectOrganizationIdList);
        organizationIdAll.addAll(enterpriseOrganizationIdList);
        OrganizationQuery query = new OrganizationQuery();
        query.withIds(organizationIdAll).withTypes(Arrays.asList(OrganizationTypeEnum.ORG.id.intValue(), OrganizationTypeEnum.ENTERPRISE.id.intValue()));
        Map<Integer, String> orgStructureNameMap = organizationService.batchFullName(query);

        String proNamesView = "";
        QueryWrapper<AccountProject> accountProjectQueryWrapper = new QueryWrapper<>();
        accountProjectQueryWrapper.eq("account_id", id);
        List<AccountProject> accountProjects = accountProjectDao.selectList(accountProjectQueryWrapper);
        if (!CollectionUtils.isEmpty(accountProjects)) {
            List<Integer> proIds = accountProjects.stream().map(AccountProject::getProjectId).collect(Collectors.toList());
            ProjectQuery canOperateProsQuery = new ProjectQuery();
            canOperateProsQuery.withIdList(proIds);
            List<Project> canOperateProjectList = projectService.list(canOperateProsQuery, null);
            if (!CollectionUtils.isEmpty(canOperateProjectList)) {
                List<String> proNames = canOperateProjectList.stream().map(Project::getName).collect(Collectors.toList());
                proNamesView = String.join("、", proNames);
            }
        }
        for (Role role : roleList) {
            AccountRolesDTO accountRolesDTO = new AccountRolesDTO();
            accountRolesDTO.setId(id);
            accountRolesDTO.setRoleId(role.getId());
            accountRolesDTO.setRoleName(role.getName());
            //填充项目名&id
            if (null != role.getProjectId()) {
                accountRolesDTO.setProjectId(role.getProjectId());
                if (null != projectNameMap.get(role.getProjectId())) {
                    accountRolesDTO.setProjectName(projectNameMap.get(role.getProjectId()));
                }
            } else {
                //企业级角色（除企管外），显示的是当前账号关联项目
                if (BusinessType.ENTERPRISE.getCode() == role.getGrade()) {
                    if (RoleTypeEnum.MANAGER.getCode() != role.getType()) {
                        accountRolesDTO.setProjectName(proNamesView);
                    }
                }
            }
            //填充组织架构名
            String orgStructureName = null;
            Integer orgId = null;
            if (Objects.nonNull(role.getProjectId())) {
                orgId = projectOrganizationMap.get(role.getProjectId());
            } else {
                orgId = enterpriseOrganizationMap.get(role.getEnterpriseId());
            }
            if (Objects.nonNull(orgId)) {
                orgStructureName = orgStructureNameMap.get(orgId);
            }
            accountRolesDTO.setOrgStructureName(orgStructureName);
            accountRolesDTOList.add(accountRolesDTO);
        }
        return accountRolesDTOList;
    }

    @Override
    public Map<Integer, List<String>> getAccountRoles(List<Integer> accountIds) {

        QueryWrapper<AccountRole> accountRoleQueryWrapper = new QueryWrapper<>();
        accountRoleQueryWrapper.in("account_id", accountIds);
        List<AccountRole> accountRoles = accountRoleService.list(accountRoleQueryWrapper);
        Map<Integer, List<Integer>> accountRoleIdMap = accountRoles.stream().collect(Collectors.groupingBy(AccountRole::getAccountId, Collectors.mapping(AccountRole::getRoleId, Collectors.toList())));
        List<Integer> roleIds = accountRoles.stream().map(i -> i.getRoleId()).distinct().collect(Collectors.toList());
        RoleQuery roleQuery = new RoleQuery();
        roleQuery.setIdList(roleIds);
        List<Role> roleList = roleService.getRoleList(null, roleQuery);
        Map<Integer, String> roleMap = roleList.stream().collect(Collectors.toMap(Role::getId, Role::getName));
        Map<Integer, List<String>> result = new HashMap<>(accountRoleIdMap.size());
        for (Map.Entry<Integer, List<Integer>> integerListEntry : accountRoleIdMap.entrySet()) {
            List<String> names = integerListEntry.getValue().stream().map(i -> roleMap.get(i)).collect(Collectors.toList());
            result.put(integerListEntry.getKey(), names);
        }
        return result;
    }

    /**
     * 根据账号id 查找项目信息
     *
     * @param id
     * @return
     */
    @Override
    public List<AccountProjectsDTO> getAccountProjects(Integer id) {
        if (null == id) {
            throw new DataException("缺少账号信息");
        }
        List<Integer> proIds = accountProjectService.list(id, null);
        ProjectQuery projectQuery = new ProjectQuery();
        projectQuery.withIdList(proIds);
        List<Project> projects = projectService.list(projectQuery, null);
        Map<Integer, String> projectNameMap = projects.stream().collect(Collectors.toMap(Project::getId, Project::getName));
        List<Integer> orgIdList = projects.stream().map(Project::getOrganizationId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(projects)) {
            return Collections.emptyList();
        }
        //通过项目id 把对应的组织链式名称获取出来 ,这里只显示到组织，示例：企业-组织
        OrganizationQuery query = new OrganizationQuery();
        query.withIds(orgIdList).withTypes(Arrays.asList(OrganizationTypeEnum.ORG.id.intValue(), OrganizationTypeEnum.ENTERPRISE.id.intValue()));
        Map<Integer, String> orgStructureNameMap = organizationService.batchFullName(query);
        List<AccountProjectsDTO> accountProjectsDTOList = new ArrayList<>();
        for (Project project : projects) {
            AccountProjectsDTO accountProjectsDTO = new AccountProjectsDTO();
            accountProjectsDTO.setId(id);
            Integer projectId = project.getId();
            accountProjectsDTO.setProjectId(projectId);
            accountProjectsDTO.setProjectName(projectNameMap.get(projectId));
            accountProjectsDTO.setOrgStructureName(orgStructureNameMap.get(project.getOrganizationId()));
            accountProjectsDTOList.add(accountProjectsDTO);
        }
        return accountProjectsDTOList;
    }


    /**
     * 删除账号
     *
     * @param accountId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultJson deleteAccount(Account operateAccount, Integer accountId) {
        log.info("正在执行删除账号，需要删除的账号id={}", accountId);
        if (null == accountId) {
            throw new DataException("缺少账号信息");
        }
        AccountDTO pushAccount = new AccountDTO();
        AccountQuery accountQuery = new AccountQuery();
        accountQuery.setIdList(Arrays.asList(accountId));
        List<AccountDTO> list = getList(accountQuery);
        if (!CollectionUtils.isEmpty(list)) {
            pushAccount = list.get(0);
        }
        QueryWrapper<AccountOrganization> accountOrganizationQueryWrapper = new QueryWrapper<>();
        accountOrganizationQueryWrapper.eq("account_id", accountId);
        accountOrganizationService.remove(accountOrganizationQueryWrapper);
        //操作人能管理的项目
        List<Project> projectList = projectService.list(null, operateAccount);
        List<Integer> proIdsDelete = projectList.stream().map(e -> e.getId()).collect(Collectors.toList());
        accountProjectService.delete(Arrays.asList(accountId), proIdsDelete);
        log.info("已经删除账号id={},项目id={}的关联关系", accountId, proIdsDelete);
        //删除操作人 可以的管理角色
        List<Role> roleList = roleService.getRoleList(operateAccount, null);
        List<Integer> roleIdList = roleList.stream().map(e -> e.getId()).collect(Collectors.toList());
        accountRoleService.deleteAccountRole(Arrays.asList(accountId), roleIdList);
        //删除第三方账号绑定关系
        AccountOpenAuth accountOpenAuth = new AccountOpenAuth();
        accountOpenAuth.setAccountId(accountId);
        accountOpenAuthService.delete(accountOpenAuth);
        //检测账号是否可以逻辑删除
        //账号 组织 关系
        QueryWrapper<AccountOrganization> accountOrgWrapper = new QueryWrapper<>();
        accountOrgWrapper.eq("account_id", accountId);
        List<AccountOrganization> accountOrganizations = accountOrganizationDao.selectList(accountOrgWrapper);
        //账号 角色 关系
        QueryWrapper<AccountRole> accountRoleWrapper = new QueryWrapper<>();
        accountRoleWrapper.eq("account_id", accountId);
        List<AccountRole> accountRoles = accountRoleDao.selectList(accountRoleWrapper);
        //账号 项目 关系
        QueryWrapper<AccountProject> accountProWrapper = new QueryWrapper<>();
        accountProWrapper.eq("account_id", accountId);
        List<AccountProject> accountProjects = accountProjectDao.selectList(accountProWrapper);
        //如果该账号无其余关联关系，即可执行删除
        if (CollectionUtils.isEmpty(accountOrganizations) && CollectionUtils.isEmpty(accountRoles) && CollectionUtils.isEmpty(accountProjects)) {
            UpdateWrapper<Account> updateWrapper = new UpdateWrapper();
            updateWrapper.eq("id", accountId);
            Account account = new Account();
            account.setId(accountId);
            account.setIsDeleted(true);
            //更新删除字段 is_deleted
            Boolean updateResult = update(account, updateWrapper);
            if (!updateResult) {
                throw new DataException("删除账号失败");
            }
            AppQuery appQuery = new AppQuery();
            appQuery.setIndustryId(operateAccount.getIndustryId());
            List<App> apps = appService.list(appQuery);
            for (App app : apps) {
                String appId = app.getAppId();
                redisUtils.remove(Constant.getTokenKey(appId, String.valueOf(accountId)));
                redisUtils.remove(Constant.getPermissionKey(appId, String.valueOf(accountId)));
                redisUtils.remove(Constant.getAccountInfoKey(appId, String.valueOf(accountId)));
                Integer appType = app.getAppType();
                redisUtils.remove(Constant.getLoginTagKey(appType, String.valueOf(accountId)));
            }
        }

        Account accountDb = findById(accountId);
        //记录操作日志
        accountLogRecord(operateAccount, LogOperationTypeEnum.DELETE, "删除账号" + "【" + accountDb.getLoginName() + "】");
        //推送到Kafka账号删除主题
        try {
            if (accountDb.getIsDeleted()) {
                accountProducer.deletePush(JSON.toJSONString(pushAccount));
            }

        } catch (Exception e) {
            log.info("当前账号数据推送到删除主题异常,账号数据={}", accountDb.toString());
        }
        return ResultJson.success("操作成功");
    }

    /**
     * 系统运维后台使用
     *
     * @param roleQuery
     * @param accountQuery
     * @param page
     * @return
     */
    @Override
    public Page<AccountDTO> pageListByRole(RoleQuery roleQuery, AccountQuery accountQuery, Page page) {
        List<Role> roles = roleService.getRoleList(null, roleQuery);
        if (CollectionUtils.isEmpty(roles)) {
            return page;
        }
        List<Integer> roleIdList = roles.stream().map(Role::getId).collect(Collectors.toList());
        if (null == accountQuery) {
            accountQuery = new AccountQuery();
        }
        accountQuery.setRoleIdList(roleIdList);
        Page<AccountDTO> accounts = getPageList(page, accountQuery);
        return accounts;

    }


    /**
     * 根据角色名 （模糊）  查出相关的项目id
     *
     * @param roleName
     * @param industryId
     * @return
     */
    @Override
    public List<Integer> getProjectIdListByRoleName(String roleName, Short industryId) {
        List<Integer> projectIdList = null;
        QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
        roleQueryWrapper.select("id");
        if (null != industryId) {
            roleQueryWrapper.eq("industry_id", industryId);
        }
        roleQueryWrapper.like("name", roleName);
        List<Role> roleList = roleService.list(roleQueryWrapper);
        if (!CollectionUtils.isEmpty(roleList)) {
            //角色ID List
            List<Integer> roleIdList = roleList.stream().map(e -> e.getId()).collect(Collectors.toList());
            QueryWrapper<RolePermission> rolePermissionQueryWrapper = new QueryWrapper<>();
            rolePermissionQueryWrapper.select("permission_id");
            rolePermissionQueryWrapper.in("role_id", roleIdList);
            List<RolePermission> rolePermissionList = rolePermissionService.list(rolePermissionQueryWrapper);
            //权限ID List
            List<Integer> permissionIdList = rolePermissionList.stream().map(e -> e.getPermissionId()).collect(Collectors.toList());
            //项目ID List
            projectIdList = projectPermissionService.getProjectIdByPermissionId(permissionIdList);
        }
        return projectIdList;
    }

    /**
     * 根据项目名 （模糊）  查出相关的项目id
     *
     * @param projectName
     * @param industryId
     * @return
     */
    @Override
    public List<Integer> getProjectIdListByProjectName(String projectName, Short industryId) {
        List<Integer> projectIdList = null;
        QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
        projectQueryWrapper.select("id");
        if (StringUtils.isNotEmpty(projectName)) {
            projectQueryWrapper.like("name", projectName);
        } else {
            return Collections.emptyList();
        }
        if (null != industryId) {
            projectQueryWrapper.eq("industry_id", industryId);
        }
        List<Project> projectList = projectDao.selectList(projectQueryWrapper);
        if (!CollectionUtils.isEmpty(projectList)) {
            projectIdList = projectList.stream().map(e -> e.getId()).collect(Collectors.toList());
        }
        return projectIdList;
    }

    /**
     * 根据企业名 （模糊）  查出相关的项目id
     *
     * @param enterpriseName
     * @param industryId
     * @return
     */
    @Override
    public List<Integer> getProjectIdListByEnterpriseName(String enterpriseName, Short industryId) {
        List<Integer> projectIdList = null;
        QueryWrapper<Enterprise> enterpriseQueryWrapper = new QueryWrapper<>();
        enterpriseQueryWrapper.select("id");
        if (null != industryId) {
            enterpriseQueryWrapper.eq("industry_id", industryId);
        }
        enterpriseQueryWrapper.like("name", enterpriseName);
        List<Enterprise> enterpriseList = enterpriseDao.selectList(enterpriseQueryWrapper);
        if (!CollectionUtils.isEmpty(enterpriseList)) {
            //企业ID List
            List<Integer> enterpriseIdList = enterpriseList.stream().map(e -> e.getId()).collect(Collectors.toList());
            QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
            projectQueryWrapper.select("id");
            projectQueryWrapper.in("enterprise_id", enterpriseIdList);
            List<Project> projectList = projectDao.selectList(projectQueryWrapper);
            //项目ID List
            projectIdList = projectList.stream().map(e -> e.getId()).collect(Collectors.toList());
        }
        return projectIdList;
    }

    /**
     * 账号数据/格式 校验
     *
     * @param account
     */
    public void accountDataVerify(Account account) {
        //业态id校验
//        if (null == account.getIndustryId()) {
//            throw new DataException("缺少业态信息");
//        }
        //姓名校验
        CentDataVerifyUtil.nameVerify(account.getName());
        //账号登录名校验
        CentDataVerifyUtil.loginNameVerify(account.getLoginName());
        //密码校验
        pwdConfig.passwordCheck(account.getPassword());
        //手机号校验
        if (StringUtils.isNotEmpty(account.getPhone())) {
            CentDataVerifyUtil.phoneVerify(account.getPhone());
        }
        //邮箱校验
        if (StringUtils.isNotEmpty(account.getEmail())) {
            CentDataVerifyUtil.emailVerify(account.getEmail());
        }
        //昵称校验
        if (StringUtils.isNotEmpty(account.getNickname())) {
            CentDataVerifyUtil.nicknameVerify(account.getNickname());
        }
        if (StringUtils.isNotEmpty(account.getIdCard())) {
            if (!ValidatorUtil.isIDCard(account.getIdCard())) {
                throw new DataException("身份证格式有误");
            }
        }
        if (StringUtils.isNotEmpty(account.getLoginName()) && StringUtils.isNotEmpty(account.getPassword())) {
            if (account.getLoginName().equals(account.getPassword())) {
                log.info("密码与用户名重复");
                throw new DataException("密码格式错误");
            }
        }
        developCheckAndHandler(account);
    }

    /**
     * 开发者信息处理
     * 创建帐号的时候校验开发者信息，如果系统里面只有一个开发者则开发者id为非必填默认为这个开发者下的帐号
     *
     * @param account
     */
    private void developCheckAndHandler(Account account) {
        if (null == account.getDevelopId()) {
            // 查找默认的开发者信息
            QueryWrapper<Developer> developerQueryWrapper = new QueryWrapper<>();
            developerQueryWrapper.eq("type", 1);
            List<Developer> developers = developerDao.selectList(developerQueryWrapper);
            if (developers.size() != 1) {
                log.error("开发者信息获取异常 {}", JSONObject.toJSONString(developers));
                throw new DataException("缺少开发者信息");
            } else {
                // 如果平台下只有一个开发者，那这个帐号默认就是这个开发者创建的，此时开发者id非必填
                account.setDevelopId(developers.get(0).getId());
            }
        } else {
            if (null == developerDao.selectById(account.getDevelopId())) {
                throw new DataException("开发者不存在");
            }
        }
    }

    /**
     * 业态下 账号唯一、手机号、邮箱、身份证 唯一验重
     *
     * @param account
     */
    @Override
    public void accountUnique(Account account) {
        if (null == account.getDevelopId()) {
            // 兼容旧接口自动填充默认的开发者
            account.setDevelopId(developerService.getDefault().getId());
        }
        if (null != account.getLoginName()) {
            //1.检查 开发者&账号 是否唯一
            QueryWrapper<Account> accountQueryWrapper = new QueryWrapper<>();
            accountQueryWrapper.eq("login_name", account.getLoginName());
            accountQueryWrapper.eq("develop_id", account.getDevelopId());
            accountQueryWrapper.eq("is_deleted", false);
            if (null != account.getId()) { // 修改
                accountQueryWrapper.ne("id", account.getId());
            }
            int count = accountDao.selectCount(accountQueryWrapper);
            if (0 < count) {
                throw new DataException("账号信息已存在");
            }
        }
        if (StringUtils.isNotEmpty(account.getPhone())) {
            //2. 开发者 & 手机号 是否唯一
            QueryWrapper<Account> accountQueryWrapper = new QueryWrapper<>();
            accountQueryWrapper.select("id");
            accountQueryWrapper.eq("develop_id", account.getDevelopId());
            accountQueryWrapper.eq("is_deleted", false);
            accountQueryWrapper.eq("phone", account.getPhone());
            if (null != account.getId()) { // 修改
                accountQueryWrapper.ne("id", account.getId());
            }
            List<Account> phoneUniqueResult = accountDao.selectList(accountQueryWrapper);
            if (phoneUniqueResult.size() > 0) {
                log.warn("手机号码已存在 {}", account.getPhone());
                throw new DataException("手机号信息已存在");
            }
        }
        if (StringUtils.isNotEmpty(account.getEmail())) {
            //3. 开发者 & 邮箱 是否唯一
            QueryWrapper<Account> accountQueryWrapper = new QueryWrapper<>();
            accountQueryWrapper.eq("email", account.getEmail());
            accountQueryWrapper.eq("develop_id", account.getDevelopId());
            accountQueryWrapper.eq("is_deleted", false);
            if (null != account.getId()) { // 修改
                accountQueryWrapper.ne("id", account.getId());
            }
            int count = accountDao.selectCount(accountQueryWrapper);
            if (0 < count) {
                throw new DataException("邮箱信息已存在");
            }
        }

        if (StringUtils.isNotEmpty(account.getIdCard())) {
            // 身份证唯一
            QueryWrapper<Account> accountQueryWrapper = new QueryWrapper<>();
            accountQueryWrapper.eq("id_card", account.getIdCard());
            accountQueryWrapper.eq("develop_id", account.getDevelopId());
            accountQueryWrapper.eq("is_deleted", false);
            if (null != account.getId()) { // 修改
                accountQueryWrapper.ne("id", account.getId());
            }
            int count = accountDao.selectCount(accountQueryWrapper);
            if (0 < count) {
                throw new DataException("身份证信息已存在");
            }
        }
    }

    /**
     * 查询条件跟操作人权限挂钩
     *
     * @param operateAccount
     * @param accountQuery
     * @return
     */
    private AccountQuery handleRequest(Account operateAccount, AccountQuery accountQuery) {
        //如果不包含游客角色类型
        if (!accountQuery.getNeedIncludeTourist() && accountQuery.getIndustryId() != null) {
            List<Role> touristRoleByIndustryId = roleService.getTouristRoleByIndustryId(accountQuery.getIndustryId());
            if (!CollectionUtils.isEmpty(touristRoleByIndustryId)) {
                List<Integer> collect = touristRoleByIndustryId.stream().map(role -> role.getId()).collect(Collectors.toList());
                List<Integer> excludeRoleIdList = accountQuery.getExcludeRoleIdList();
                if (excludeRoleIdList == null) {
                    excludeRoleIdList = new ArrayList<>();
                }
                excludeRoleIdList.addAll(collect);
                accountQuery.setExcludeRoleIdList(excludeRoleIdList);
            }
        }
        //根据企业ID，项目ID，超管角色ID,是否需要企管、超管、普通内置角色等 筛选出符合条件的账号
        accountQuery = screenAccountIds(accountQuery);
        //与操作人无关的时候，直接返回查询条件
        if (null == operateAccount) {
            return accountQuery;
        }
        if (null == operateAccount.getId()) {
            return accountQuery;
        }
        //剩余的是与操作人员有关的
        RoleTypeDTO roleTypeDTO = roleService.getAccountRoleType(operateAccount.getId());
        RoleTypeEnum roleTypeEnum = roleTypeDTO.getRoleTypeEnum();
        //超管
        if (RoleTypeEnum.SUPPER_MANAGER.equals(roleTypeEnum)) {
            //超管能管理该业态下的所有账号
            accountQuery.setIndustryId(operateAccount.getIndustryId());
            return accountQuery;
        }
        // 运营人员
        if (RoleTypeEnum.OPERATE_MANAGER.equals(roleTypeEnum)) {
            List<Integer> accountIdResult = new ArrayList<>();
            //当前运管 能管理的企业下的账号id
            if (!CollectionUtils.isEmpty(roleTypeDTO.getEnterpriseIdList())) {
                List<Integer> enterpriseIdList = roleTypeDTO.getEnterpriseIdList();
                QueryWrapper<AccountOrganization> accountOrganizationQueryWrapper = new QueryWrapper<>();
                accountOrganizationQueryWrapper.in("enterprise_id", enterpriseIdList);
                List<AccountOrganization> accountOrganizations = accountOrganizationDao.selectList(accountOrganizationQueryWrapper);
                List<Integer> accountIdList = accountOrganizations.stream().map(e -> e.getAccountId()).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(accountQuery.getIdList())) {
                    List<Integer> accountResult = accountIdList.stream().filter(accountQuery.getIdList()::contains).collect(Collectors.toList());
                    accountIdResult.addAll(accountResult);
                } else {
                    accountIdResult.addAll(accountIdList);
                }
            }
            //当前运管 能管理的项目下的账号id
            if (!CollectionUtils.isEmpty(roleTypeDTO.getProjectIdList())) {
                List<Integer> projectIdList = roleTypeDTO.getProjectIdList();
                List<Integer> accountIdList = accountProjectService.list(null, projectIdList);
                if (!CollectionUtils.isEmpty(accountQuery.getIdList())) {
                    List<Integer> accountResult = accountIdList.stream().filter(accountQuery.getIdList()::contains).collect(Collectors.toList());
                    accountIdResult.addAll(accountResult);
                } else {
                    accountIdResult.addAll(accountIdList);
                }
            }
            //去重后新增 id主键 条件
            HashSet accountIds = new HashSet(accountIdResult);
            accountIdResult.clear();
            accountIdResult.addAll(accountIds);
            //和传入进来的主键id取交集
            if (!CollectionUtils.isEmpty(accountQuery.getIdList())) {
                accountIdResult = accountIdResult.stream().filter(accountQuery.getIdList()::contains).collect(Collectors.toList());
            }
            accountQuery.setIdList(accountIdResult);
            return accountQuery;

        }
        //企业管理员
        if (RoleTypeEnum.ENT_MANAGER.equals(roleTypeEnum)) {
            List<Integer> enterpriseIdList = roleTypeDTO.getEnterpriseIdList();
            List<Integer> accountIdResult = new ArrayList<>();
            QueryWrapper<AccountOrganization> accountOrganizationQueryWrapper = new QueryWrapper<>();
            accountOrganizationQueryWrapper.in("enterprise_id", enterpriseIdList);
            List<AccountOrganization> accountOrganizations = accountOrganizationDao.selectList(accountOrganizationQueryWrapper);
            List<Integer> accountIdList = accountOrganizations.stream().map(e -> e.getAccountId()).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(accountQuery.getIdList())) {
                List<Integer> accountResult = accountIdList.stream().filter(accountQuery.getIdList()::contains).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(accountIdResult)) {
                    log.info("企业管理员无法获取这些账号数据，查询结果将为空,ids={}", accountQuery.getIdList());
                    accountQuery.setReturnEmpty(true);
                }
                accountIdResult.addAll(accountResult);
            } else {
                accountIdResult.addAll(accountIdList);
            }
            accountQuery.setIdList(accountIdResult);
            return accountQuery;
        }
        //项目管理员
        if (RoleTypeEnum.PRO_MANAGER.equals(roleTypeEnum)) {
            List<Integer> projectIdList = roleTypeDTO.getProjectIdList();
            List<Integer> accountIdResult = new ArrayList<>();
            List<Integer> accountIdList = accountProjectService.list(null, projectIdList);
            if (!CollectionUtils.isEmpty(accountQuery.getIdList())) {
                List<Integer> accountResult = accountIdList.stream().filter(accountQuery.getIdList()::contains).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(accountIdResult)) {
                    log.info("项目管理员无法获取这些账号数据，查询结果将为空,ids={}", accountQuery.getIdList());
                    accountQuery.setReturnEmpty(true);
                }
                accountIdResult.addAll(accountResult);
            } else {
                accountIdResult.addAll(accountIdList);
            }
            accountQuery.setIdList(accountIdResult);
            return accountQuery;
        }
        if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(accountQuery.getOrganizationIds()) && !accountQuery.isCurrentOrganization()) {
            OrganizationQuery organizationQuery = new OrganizationQuery();
            organizationQuery.withIds(accountQuery.getOrganizationIds());
            List<Organization> parentAndChild = organizationService.child(organizationQuery);
            accountQuery.setOrganizationIds(parentAndChild.stream().map(i -> i.getId()).collect(Collectors.toList()));
        }
        return accountQuery;
    }


    /**
     * 动态查询封装器生成
     *
     * @param accountQuery
     * @return
     */
    private QueryWrapper<Account> handleParams(AccountQuery accountQuery) {
        QueryWrapper<Account> accountQueryWrapper = new QueryWrapper<>();
        accountQueryWrapper.eq("is_deleted", false);
        if (null == accountQuery) {
            return accountQueryWrapper;
        }
        //返回空数据
        if (null != accountQuery.getReturnEmpty()) {
            if (accountQuery.getReturnEmpty()) {
                accountQueryWrapper.eq("id", -1);
                return accountQueryWrapper;
            }
        }
        if (!CollectionUtils.isEmpty(accountQuery.getSelectColumnList())) {
            String[] fieldNameArray = accountQuery.getSelectColumnList().stream().toArray(String[]::new);
            accountQueryWrapper.select(fieldNameArray);
        }
        if (null != accountQuery.getExcludeId()) {
            accountQueryWrapper.ne("id", accountQuery.getExcludeId());
        }
        if (!CollectionUtils.isEmpty(accountQuery.getExcludeIdList())) {
            accountQueryWrapper.notIn("id", accountQuery.getExcludeIdList());
        }
        if (null != accountQuery.getId()) {
            if (!CollectionUtils.isEmpty(accountQuery.getIdList())) {
                List<Integer> idList = accountQuery.getIdList();
                idList.add(accountQuery.getId());
                accountQuery.setIdList(idList);
            } else {
                accountQuery.setIdList(Arrays.asList(accountQuery.getId()));
            }
        }

        if (!CollectionUtils.isEmpty(accountQuery.getIdList())) {
            accountQueryWrapper.in("id", accountQuery.getIdList());
        }

        if (null != accountQuery.getIndustryId()) {
            accountQueryWrapper.eq("industry_id", accountQuery.getIndustryId());
        }
        if (StringUtils.isNotEmpty(accountQuery.getLoginName())) {
            accountQueryWrapper.eq("login_name", accountQuery.getLoginName());
        }
        if (StringUtils.isNotEmpty(accountQuery.getPhone())) {
            accountQueryWrapper.eq("phone", accountQuery.getPhone());
        }
        if (!CollectionUtils.isEmpty(accountQuery.getPhoneList())) {
            accountQueryWrapper.in("phone", accountQuery.getPhoneList());
        }
        if (StringUtils.isNotEmpty(accountQuery.getFaceId())) {
            accountQueryWrapper.eq("face_id", accountQuery.getFaceId());
        }
        if (StringUtils.isNotEmpty(accountQuery.getEmail())) {
            accountQueryWrapper.eq("email", accountQuery.getEmail());
        }
        if (StringUtils.isNotEmpty(accountQuery.getLikeLoginName())) {
            accountQueryWrapper.like("login_name", accountQuery.getLikeLoginName());
        }
        if (StringUtils.isNotEmpty(accountQuery.getLikePhone())) {
            accountQueryWrapper.like("phone", accountQuery.getLikePhone());
        }
        if (StringUtils.isNotEmpty(accountQuery.getLikeName())) {
            accountQueryWrapper.like("name", accountQuery.getLikeName());
        }
        if (StringUtils.isNotEmpty(accountQuery.getIdCard())) {
            accountQueryWrapper.eq("id_card", accountQuery.getIdCard());
        }
        if (!CollectionUtils.isEmpty(accountQuery.getIdCardList())) {
            accountQueryWrapper.in("id_card", accountQuery.getIdCardList());
        }
        if (null != accountQuery.getDevelopId()) {
            accountQueryWrapper.eq("develop_id", accountQuery.getDevelopId());
        }
        return accountQueryWrapper;
    }

    @Override
    public AccountDetailVO getDetail(Short industryId, Account operateAccount, Integer id) {
        Account account = findById(id);
        if (null == account) {
            throw new DataException("账号不存在");
        }
        OrganizationQuery organizationQuery = new OrganizationQuery();
        organizationQuery.withAccountId(account.getId());
        organizationQuery.withIndustryId(operateAccount.getIndustryId());
        Organization organization = organizationService.find(organizationQuery);
        List<Project> projects = new ArrayList<>();
        List<Role> roles = roleService.getRoleListByAccountId(id);
        Integer entId = null;
        String entName = "";
        if (null != organization) {
            entId = organization.getEnterpriseId();
            Enterprise enterprise = enterpriseService.findById(entId);
            entName = enterprise.getName();
            List<Integer> projectIds = accountProjectService.list(id, null);
            if (!CollectionUtils.isEmpty(projectIds)) {
                ProjectQuery projectQuery = new ProjectQuery();
                projectQuery.withIdList(projectIds);
                projects = projectService.list(projectQuery, null);
            }
        }
        AccountDetailVO accountDetailVO = new AccountDetailVO();
        //操作人是超管/企管/项目管理员，能查出来的角色信息不同
        superManagerRoleSetter(accountDetailVO, roles, projects);
        BeanUtils.copyProperties(account, accountDetailVO);
        accountDetailVO.setEnterpriseId(entId);
        accountDetailVO.setEnterpriseName(entName);
        if (StringUtils.isNotEmpty(account.getName())) {
            String name = account.getName();
            accountDetailVO.setName(EmojiParser.parseToUnicode(name));
        }
        if (StringUtils.isNotEmpty(account.getNickname())) {
            String name = account.getNickname();
            accountDetailVO.setNickname(EmojiParser.parseToUnicode(name));
        }
        if (null != account.getDevelopId()) {
            Developer developer = developerDao.selectById(account.getDevelopId());
            accountDetailVO.setDeveloper(developer);
        } else {
            log.error("账号 {} 的详情缺少开发者信息", id);
        }
        return accountDetailVO;
    }
    /**
     * 超管角色能看到的角色设置
     *
     * @param accountDetailVO
     * @param roles
     * @param projects
     */
    private void superManagerRoleSetter(AccountDetailVO accountDetailVO, List<Role> roles, List<Project> projects) {
        List<String> resultRoles = new ArrayList<>();
        for (Role role : roles) {
            resultRoles.add("role-" + role.getId() + "-" + role.getName());
        }
        accountDetailVO.setRoleList(resultRoles);
        List<String> resultProjects = new ArrayList<>();
        if (!CollectionUtils.isEmpty(projects)) {
            for (Project project : projects) {
                resultProjects.add(project.getId() + "-" + project.getOrganizationId() + "-" + project.getName());
            }
        }
        accountDetailVO.setProjectList(resultProjects);
        if (!CollectionUtils.isEmpty(roles)) {
            accountDetailVO.setRoleIds(roles.stream().map(i -> i.getId()).collect(Collectors.toList()));
        }
    }

    /**
     * 项目管理员能看到的角色设置
     *
     * @param accountDetailVO
     * @param roles
     * @param projects
     * @param entId
     */
    private void enterpriseRoleSetter(AccountDetailVO accountDetailVO, List<Role> roles, List<Project> projects, Integer entId) {
        List<String> resultRoles = new ArrayList<>();
        for (Role role : roles) {
            if (null != role.getEnterpriseId()) {
                if (entId.equals(role.getEnterpriseId())) {
                    resultRoles.add("role-" + role.getId() + "-" + role.getName());
                }
            }
        }
        accountDetailVO.setRoleList(resultRoles);
        List<String> resultProjects = new ArrayList<>();
        if (!CollectionUtils.isEmpty(projects)) {
            for (Project project : projects) {
                if (null != project.getEnterpriseId()) {
                    if (null != entId) {
                        if (entId.equals(project.getEnterpriseId())) {
                            resultProjects.add(project.getId() + "-" + project.getOrganizationId() + "-" + project.getName());
                        }
                    }

                }
            }
        }
        accountDetailVO.setProjectList(resultProjects);
    }

    /**
     * 项目管理员可以查看的角色设置
     *
     * @param accountDetailVO
     * @param roles
     * @param projects
     * @param accountRoleType
     */
    private void projectManagerRoleSetter(AccountDetailVO accountDetailVO, List<Role> roles, List<Project> projects, RoleTypeDTO accountRoleType) {
        List<Integer> projectIdList = accountRoleType.getProjectIdList();
        List<String> resultRoles = new ArrayList<>();
        for (Role role : roles) {
            if (null != role.getProjectId()) {
                if (projectIdList.contains(role.getProjectId())) {
                    resultRoles.add("role-" + role.getId() + "-" + role.getName());
                }
            }
        }
        accountDetailVO.setRoleList(resultRoles);
        List<String> resultProjects = new ArrayList<>();
        if (!CollectionUtils.isEmpty(projects)) {
            for (Project project : projects) {
                if (null != project.getId()) {
                    if (projectIdList.contains(project.getId())) {
                        resultProjects.add(project.getId() + "-" + project.getOrganizationId() + "-" + project.getName());
                    }
                }
            }
        }
        accountDetailVO.setProjectList(resultProjects);
    }

    /**
     * 修改手机号
     *
     * @param operateAccount
     * @param accountPersonalDTO
     * @return
     */
    @Override
    public ResultJson phoneEdit(Account operateAccount, AccountPersonalDTO accountPersonalDTO) {
        if (null == operateAccount.getIndustryId()) {
            return ResultJson.fail("缺少业态信息");
        }
        ResultJson resultJson = null;
        String phone = Optional.ofNullable(accountPersonalDTO.getPhone()).orElseThrow(() -> new DataException("手机号不能为空"));
        String msgCode = Optional.ofNullable(accountPersonalDTO.getMsgCode()).orElseThrow(() -> new DataException("短信验证码不能为空"));
        //新手机的 验证短信
        //短信验证码校验
        resultJson = messageCodeService.phoneMsgCodeVerify(String.valueOf(operateAccount.getIndustryId()), phone, msgCode, true);
        if (CodeEnum.SUCCESS.code != resultJson.getCode()) {
            return resultJson;
        }
        redisUtils.remove(operateAccount.getIndustryId() + "_" + Constant.MSG_CODE_PREFIX + phone);
        //调用修改手机接口
        Account account = new Account();
        account.setId(operateAccount.getId());
        //需要修改手机号
        CentDataVerifyUtil.phoneVerify(phone);
        //验证开发者下，手机号未被使用
        AccountQuery accountQuery = new AccountQuery();
        if (null != operateAccount.getDevelopId()) {
            accountQuery.setDevelopId(operateAccount.getDevelopId());
        }
        accountQuery.setPhone(phone);
        try {
            List<Account> accountList = getAccountList(null, accountQuery);
            if (!CollectionUtils.isEmpty(accountList)) {
                for (Account accountDb : accountList) {
                    if (!operateAccount.getId().equals(accountDb.getId())) {
                        return ResultJson.fail("手机号已被使用");
                    }
                }
            }
            account.setPhone(phone);
            account.setIndustryId(operateAccount.getIndustryId());
            //修改个人中心信息 ，只修改手机号
            resultJson = modifyPersonalInfo(account);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultJson.fail(e.getMessage());
        }
        return resultJson;
    }


    /**
     * 判断当前操作账号是否可以使用这个项目
     *
     * @param account
     * @param projectId
     * @return
     */
    @Override
    public ResultJson checkOperateProject(Account account, Integer projectId) {
        Integer accountId = account.getId();
        Boolean checkResult = false;
        //获取当前登录操作账号的角色身份
        RoleTypeDTO accountRoleType = roleService.getAccountRoleType(accountId);
        RoleTypeEnum operateRoleType = accountRoleType.getRoleTypeEnum();
        //超管
        if (RoleTypeEnum.SUPPER_MANAGER.getCode() == operateRoleType.getCode()) {
            checkResult = true;
        } else if (RoleTypeEnum.ENT_MANAGER.getCode() == operateRoleType.getCode()) {
            //企管能管理的项目id
            List<Integer> enterpriseIdList = accountRoleType.getEnterpriseIdList();
            ProjectQuery projectQuery = new ProjectQuery();
            projectQuery.withEnterpriseIds(enterpriseIdList);
            List<Project> projects = projectService.list(projectQuery, null);
            List<Integer> projectIdList = projects.stream().map(Project::getId).collect(Collectors.toList());
            if (projectIdList.contains(projectId)) {
                checkResult = true;
            }
        } else if (RoleTypeEnum.PRO_MANAGER.getCode() == operateRoleType.getCode()) {
            //项目管理员 只能查看 项目管理员账号 和 普通账号
            List<Integer> projectIdList = accountRoleType.getProjectIdList();
            if (projectIdList.contains(projectId)) {
                checkResult = true;
            }
        } else {
            ProjectQuery projectQuery = new ProjectQuery();
            projectQuery.withAccountId(accountId);
            List<Project> projects = projectService.list(projectQuery, null);
            List<Integer> projectIdList = projects.stream().map(Project::getId).collect(Collectors.toList());
            if (projectIdList.contains(projectId)) {
                checkResult = true;
            }
        }
        return ResultJson.success(checkResult);
    }


    /**
     * 根据角色反查对应的项目和企业ids
     * 0829改版后 改为校验数据的方法
     *
     * @param account
     * @param enterpriseIds
     * @param projectIds
     * @param roleIds
     * @return
     */
    public Map<String, List<Integer>> convertEntAndProIdMap(Account account, List<Integer> enterpriseIds, List<Integer> projectIds, List<Integer> roleIds) {
        Map<String, List<Integer>> resultMap = new HashMap<>();
//        List<Role> roles = roleService.listByIds(roleIds);
//        List<Integer> collect = roles.stream().map(i -> i.getEnterpriseId()).distinct().collect(Collectors.toList());
//        // 排除没有选角色的企业
//        enterpriseIds.retainAll(collect);
//        List<Project> projects = projectService.listByIds(projectIds);
//        // 排除不是这些企业下的项目
//        List<Integer> collect1 = projects.stream().filter(i -> enterpriseIds.contains(i.getEnterpriseId())).map(j -> j.getId()).collect(Collectors.toList());
        resultMap.put("entIdList", enterpriseIds);
        resultMap.put("proIdList", projectIds);
        return resultMap;
    }


    /**
     * 转换出 accountId为key，关联的企业信息为value的map
     * 里面的map信息 entName entIds
     *
     * @param accountIdList
     * @return
     */
    public Map<Integer, Map<String, Object>> convertAccountEntMap(AccountQuery accountQuery, List<Integer> accountIdList) {
        Map<Integer, Map<String, Object>> accountEnterpriseInfoMap = new HashMap<>();
        //根据企业id获取 账号、企业关联的数据
        List<AccountDetailDTO> accountEnterpriseInfoList = getAccountEnterpriseInfoByIdList(null, accountIdList);
        List<Integer> needDataFilterEnterpriseIds = new ArrayList<>();
        List<AccountDetailDTO> accountEnterpriseResult = new ArrayList<>();
        //数据过滤
        if (accountQuery.getNeedDataFilter()) {
            if (CollectionUtils.isEmpty(accountQuery.getEnterpriseIdList())) {
                //通过项目反查所属企业作为过滤条件
                if (!CollectionUtils.isEmpty(accountQuery.getProjectIdList())) {
                    ProjectQuery projectQuery = new ProjectQuery();
                    projectQuery.withIdList(accountQuery.getProjectIdList());
                    List<Project> projects = projectService.list(projectQuery, null);
                    if (!CollectionUtils.isEmpty(projects)) {
                        List<Integer> entIds = projects.stream().map(Project::getEnterpriseId).collect(Collectors.toList());
                        needDataFilterEnterpriseIds.addAll(entIds);
                    }
                }
            } else {
                needDataFilterEnterpriseIds.addAll(accountQuery.getEnterpriseIdList());
            }

            if (!CollectionUtils.isEmpty(needDataFilterEnterpriseIds)) {
                for (AccountDetailDTO accountDetailDTO : accountEnterpriseInfoList) {
                    Integer enterpriseId = accountDetailDTO.getEnterpriseId();
                    if (needDataFilterEnterpriseIds.contains(enterpriseId)) {
                        accountEnterpriseResult.add(accountDetailDTO);
                    }
                }
            }
        }
        if (CollectionUtils.isEmpty(accountEnterpriseResult)) {
            accountEnterpriseResult.addAll(accountEnterpriseInfoList);
        }
        for (AccountDetailDTO accountDetailDTO : accountEnterpriseResult) {
            Integer accountId = accountDetailDTO.getAccountId();
            Map<String, Object> entMap = new HashMap<>();
            if (accountEnterpriseInfoMap.containsKey(accountId)) {
                entMap = accountEnterpriseInfoMap.get(accountId);
                StringBuffer entNameStr = new StringBuffer();
                if (null != entMap.get("entName")) {
                    entNameStr = new StringBuffer(String.valueOf(entMap.get("entName")));
                }
                entNameStr.append("、").append(accountDetailDTO.getEnterpriseName());
                entMap.put("entName", entNameStr);
                List<Integer> entIds = new ArrayList<>();
                if (null != entMap.get("entIds")) {
                    if (!CollectionUtils.isEmpty((List<Integer>) entMap.get("entIds"))) {
                        entIds = (List<Integer>) entMap.get("entIds");
                    }
                }
                Integer entId = accountDetailDTO.getEnterpriseId();
                List<Integer> entIdSaveList = new ArrayList<>(entIds);
                entIdSaveList.add(entId);
                entMap.put("entIds", entIdSaveList);
                //填充企业类型 todo
                List<String> entTypes = new ArrayList<>();
                if (null != entMap.get("entTypes")){
                    if (!CollectionUtils.isEmpty((List<String>) entMap.get("entTypes"))){
                        entTypes = (List<String>) entMap.get("entTypes");
                    }
                }
                String entType = accountDetailDTO.getEnterpriseType();
                List<String> entTypeList = new ArrayList<>(entTypes);
                entTypeList.add(entType);
                entMap.put("entTypes", entTypeList);
                accountEnterpriseInfoMap.put(accountId, entMap);
            } else {
                entMap.put("entName", accountDetailDTO.getEnterpriseName());
                entMap.put("entIds", Arrays.asList(accountDetailDTO.getEnterpriseId()));
                //填充企业类型 todo
                entMap.put("entTypes",Arrays.asList(accountDetailDTO.getEnterpriseType()));
                accountEnterpriseInfoMap.put(accountId, entMap);
            }
        }
        return accountEnterpriseInfoMap;
    }


    /**
     * 转换出 accountId为key，关联的角色名称为value的map
     * 里面的map信息 roleName、roleIds、roleType
     *
     * @param accountIdList
     * @return
     */
    public Map<Integer, Map<String, Object>> convertAccountRoleMap(AccountQuery accountQuery, List<Integer> accountIdList, List<Integer> roleIdList) {
        Map<Integer, Map<String, Object>> accountRoleMap = new HashMap<>();
        //根据账户和id获取 账号、角色关联的数据
        List<AccountDetailDTO> accountRoleInfoList = getAccountRoleInfoByIdList(accountIdList, roleIdList);
        Set<AccountDetailDTO> accountRoleResultSet = new HashSet<>();
        if (accountQuery.getNeedDataFilter()) {
            if (!CollectionUtils.isEmpty(accountQuery.getRoleIdList())) {
                List<Integer> needDataFilterRoleIds = new ArrayList<>(accountQuery.getRoleIdList());
                for (AccountDetailDTO accountDetailDTO : accountRoleInfoList) {
                    Integer roleId = accountDetailDTO.getRoleId();
                    if (needDataFilterRoleIds.contains(roleId)) {
                        accountRoleResultSet.add(accountDetailDTO);
                    }
                }
            }
            if (!CollectionUtils.isEmpty(accountQuery.getProjectIdList())) {
                List<Integer> projectIdList = accountQuery.getProjectIdList();
                for (AccountDetailDTO accountDetailDTO : accountRoleInfoList) {
                    Integer projectId = accountDetailDTO.getProjectId();
                    if (null != projectId) {
                        if (projectIdList.contains(projectId)) {
                            accountRoleResultSet.add(accountDetailDTO);
                        }
                    }
                }
            }
        }

        List<AccountDetailDTO> accountRoleResult = new ArrayList<>();
        if (CollectionUtils.isEmpty(accountRoleResultSet)) {
            accountRoleResult.addAll(accountRoleInfoList);
        } else {
            accountRoleResult.addAll(accountRoleResultSet);
        }

        for (AccountDetailDTO accountDetailDTO : accountRoleResult) {
            Integer accountId = accountDetailDTO.getAccountId();
            Map<String, Object> roleMap = new HashMap<>();
            if (accountRoleMap.containsKey(accountId)) {
                roleMap = accountRoleMap.get(accountId);
                StringBuffer roleNameStr = new StringBuffer();
                if (null != roleMap.get("roleName")) {
                    roleNameStr = new StringBuffer(String.valueOf(accountRoleMap.get(accountId).get("roleName")));
                }
                roleNameStr.append("、").append(accountDetailDTO.getRoleName());
                roleMap.put("roleName", roleNameStr.toString());
                List<Integer> roleIds = new ArrayList<>();
                if (null != roleMap.get("roleIds")) {
                    if (!CollectionUtils.isEmpty((List<Integer>) roleMap.get("roleIds"))) {
                        roleIds = (List<Integer>) roleMap.get("roleIds");
                    }
                }
                Integer roleId = accountDetailDTO.getRoleId();
                List<Integer> roleIdSaveList = new ArrayList<>(roleIds);
                roleIdSaveList.add(roleId);
                roleMap.put("roleIds", roleIdSaveList);
                accountRoleMap.put(accountId, roleMap);
            } else {
                roleMap.put("roleName", accountDetailDTO.getRoleName());
                roleMap.put("roleIds", Arrays.asList(accountDetailDTO.getRoleId()));
                accountRoleMap.put(accountId, roleMap);
            }
            Integer accountRoleType = accountDetailDTO.getRoleType();
            if (null == roleMap.get("roleType")) {
                roleMap.put("roleType", accountRoleType);
            } else {
                Integer roleType = (Integer) roleMap.get("roleType");
                if (accountRoleType < roleType) {
                    roleMap.put("roleType", accountRoleType);
                }
            }
        }
        return accountRoleMap;
    }


    /**
     * 转换出 accountId为key，关联的项目名称为value的map
     *
     * @param accountIdList
     * @return
     */
    public Map<Integer, Map<String, Object>> convertAccountProMap(AccountQuery accountQuery, List<Integer> accountIdList) {
        Map<Integer, Map<String, Object>> accountProMap = new HashMap<>();
        //根据账户和id获取 账号、项目关联的数据
        List<AccountDetailDTO> accountProjectInfoList = getAccountProjectInfoByIdList(accountIdList);

        List<Integer> needDataFilterProjectIds = new ArrayList<>();
        List<AccountDetailDTO> accountProjectResult = new ArrayList<>();
        //数据过滤
        if (accountQuery.getNeedDataFilter()) {
            if (CollectionUtils.isEmpty(accountQuery.getProjectIdList())) {

                if (!CollectionUtils.isEmpty(accountQuery.getEnterpriseIdList())) {
                    ProjectQuery projectQuery = new ProjectQuery();
                    projectQuery.withEnterpriseIds(accountQuery.getEnterpriseIdList());
                    List<Project> projects = projectService.list(projectQuery, null);
                    if (!CollectionUtils.isEmpty(projects)) {
                        List<Integer> proIds = projects.stream().map(Project::getId).collect(Collectors.toList());
                        needDataFilterProjectIds.addAll(proIds);
                    }
                }
            } else {
                needDataFilterProjectIds.addAll(accountQuery.getProjectIdList());
            }
            if (!CollectionUtils.isEmpty(needDataFilterProjectIds)) {
                for (AccountDetailDTO accountDetailDTO : accountProjectInfoList) {
                    Integer projectId = accountDetailDTO.getProjectId();

                    if (needDataFilterProjectIds.contains(projectId)) {
                        accountProjectResult.add(accountDetailDTO);
                    }
                }
            }
        }
        if (CollectionUtils.isEmpty(accountProjectResult)) {
            accountProjectResult.addAll(accountProjectInfoList);
        }
        for (AccountDetailDTO accountDetailDTO : accountProjectResult) {
            Integer accountId = accountDetailDTO.getAccountId();
            Map<String, Object> proMap = new HashMap<>();
            if (accountProMap.containsKey(accountId)) {
                proMap = accountProMap.get(accountId);
                StringBuffer proNameStr = new StringBuffer();
                if (null != proMap.get("proName")) {
                    proNameStr = new StringBuffer(String.valueOf(proMap.get("proName")));
                }
                proNameStr.append("、").append(accountDetailDTO.getProjectName());
                proMap.put("proName", proNameStr);
                List<Integer> proIds = new ArrayList<>();
                if (null != proMap.get("proIds")) {
                    if (!CollectionUtils.isEmpty((List<Integer>) proMap.get("proIds"))) {
                        proIds = (List<Integer>) proMap.get("proIds");
                    }

                }
                Integer proId = accountDetailDTO.getProjectId();
                List<Integer> proIdSaveList = new ArrayList<>(proIds);
                proIdSaveList.add(proId);
                proMap.put("proIds", proIdSaveList);
                accountProMap.put(accountId, proMap);
            } else {
                proMap.put("proName", accountDetailDTO.getProjectName());
                proMap.put("proIds", Arrays.asList(accountDetailDTO.getProjectId()));
                accountProMap.put(accountId, proMap);
            }
        }
        return accountProMap;
    }


    /**
     * 移除当前账号的权限缓存信息
     *
     * @param id
     */
    public void removeAccountAuthCache(Integer id) {
        if (null == id) {
            throw new DataException("缺少账号信息");
        }
        List<String> removeKeys = new ArrayList<>();
        List<App> apps = appDao.selectList(null);
        List<String> appIdList = apps.stream().map(e -> e.getAppId()).collect(Collectors.toList());
        for (String appIdStr : appIdList) {
            String tokenKey = "";
            String permissionKey = "";
            String userInfoKey = "";
            if (Constant.ADMIN_APPID.equals(appIdStr)) {
                tokenKey = Constant.getAdminTokenKey(String.valueOf(id));
            } else {
                tokenKey = Constant.getTokenKey(appIdStr, String.valueOf(id));
                permissionKey = Constant.getPermissionKey(appIdStr, String.valueOf(id));
                userInfoKey = Constant.getAccountInfoKey(appIdStr, String.valueOf(id));
            }
            if (StringUtils.isNotEmpty(tokenKey)) {
                removeKeys.add(tokenKey);
            }
            if (StringUtils.isNotEmpty(permissionKey)) {
                removeKeys.add(permissionKey);
            }
            if (StringUtils.isNotEmpty(userInfoKey)) {
                removeKeys.add(userInfoKey);
            }
        }
        //把此账号改密前相关的缓存都清除
        if (!CollectionUtils.isEmpty(removeKeys)) {
            for (String key : removeKeys) {
                redisUtils.remove(key);
            }
        }
    }

    /**
     * 筛选 出 需要查找的 账号id
     *
     * @param accountQuery
     * @return
     */
    public AccountQuery screenAccountIds(AccountQuery accountQuery) {


        if (!CollectionUtils.isEmpty(accountQuery.getPermissionCodes())) {
            RoleQuery roleQuery = new RoleQuery();
            if (null != accountQuery.getIndustryId()) {
                roleQuery.setIndustryIdList(Arrays.asList(accountQuery.getIndustryId()));
            }
            roleQuery.setPermissionCodes(accountQuery.getPermissionCodes());
            List<Role> roleList = roleService.getRoleList(null, roleQuery);
            List<Integer> roleIds = roleList.stream().map(Role::getId).collect(Collectors.toList());
            List<Integer> accountIdList = accountRoleService.findByRoleId(roleIds);
            if (!CollectionUtils.isEmpty(accountQuery.getIdList())) {
                List<Integer> accountIdResult = accountIdList.stream().filter(accountQuery.getIdList()::contains).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(accountIdResult)) {
                    log.info("权限码相关的这些账号数据和原需要查询的账号数据，交集为空,ids={}", accountQuery.getIdList());
                    accountQuery.setReturnEmpty(true);
                    return accountQuery;
                }
                accountQuery.setIdList(accountIdResult);
            } else {
                accountQuery.setIdList(accountIdList);
            }
        }

        //根据企业ids 找账号
        if (!CollectionUtils.isEmpty(accountQuery.getEnterpriseIdList())) {
            QueryWrapper<AccountOrganization> accountOrganizationQueryWrapper = new QueryWrapper<>();
            accountOrganizationQueryWrapper.in("enterprise_id", accountQuery.getEnterpriseIdList());
            List<AccountOrganization> accountOrganizations = accountOrganizationDao.selectList(accountOrganizationQueryWrapper);
            //将企业关联的账号和 传入的账号id  做交集
            if (!CollectionUtils.isEmpty(accountOrganizations)) {
                List<Integer> accountIdList = accountOrganizations.stream().map(AccountOrganization::getAccountId).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(accountQuery.getIdList())) {
                    List<Integer> accountIdResult = accountIdList.stream().filter(accountQuery.getIdList()::contains).collect(Collectors.toList());
                    if (CollectionUtils.isEmpty(accountIdResult)) {
                        log.info("企业下不存在这些账号数据，查询结果将为空,ids={}", accountQuery.getIdList());
                        accountQuery.setReturnEmpty(true);
                        return accountQuery;
                    }
                    accountQuery.setIdList(accountIdResult);
                } else {
                    accountQuery.setIdList(accountIdList);
                }
            }
        }
        //根据项目id找账号
        if (!CollectionUtils.isEmpty(accountQuery.getProjectIdList())) {
            List<Integer> accountIdList = accountProjectService.list(null, accountQuery.getProjectIdList());
            //将项目关联的账号和 传入的账号id  做交集
            if (!CollectionUtils.isEmpty(accountIdList)) {
                if (!CollectionUtils.isEmpty(accountQuery.getIdList())) {
                    List<Integer> accountIdResult = accountIdList.stream().filter(accountQuery.getIdList()::contains).collect(Collectors.toList());
                    if (CollectionUtils.isEmpty(accountIdResult)) {
                        log.info("项目下不存在这些账号数据，查询结果将为空,ids={}", accountQuery.getIdList());
                        accountQuery.setReturnEmpty(true);
                        return accountQuery;
                    }
                    accountQuery.setIdList(accountIdResult);
                } else {
                    accountQuery.setIdList(accountIdList);
                }
            } else {
                accountQuery.setReturnEmpty(true);
                return accountQuery;
            }
        }

        //根据角色id找账号
        if (!CollectionUtils.isEmpty(accountQuery.getRoleIdList())) {
            List<Integer> accountIdList = accountRoleService.findByRoleId(accountQuery.getRoleIdList());
            //将角色关联的账号和 传入的账号id  做交集
            if (!CollectionUtils.isEmpty(accountIdList)) {
                //将项目关联的账号和 传入的账号id  做交集
                if (!CollectionUtils.isEmpty(accountIdList)) {
                    if (!CollectionUtils.isEmpty(accountQuery.getIdList())) {
                        List<Integer> accountIdResult = accountIdList.stream().filter(accountQuery.getIdList()::contains).collect(Collectors.toList());
                        if (CollectionUtils.isEmpty(accountIdResult)) {
                            log.info("角色下不存在这些账号数据，查询结果将为空,ids={}", accountQuery.getIdList());
                            accountQuery.setReturnEmpty(true);
                            return accountQuery;
                        }
                        accountQuery.setIdList(accountIdResult);
                    } else {
                        accountQuery.setIdList(accountIdList);
                    }
                } else {
                    accountQuery.setReturnEmpty(true);
                    return accountQuery;
                }
            }
        }
        //特殊兼容超管的账号数据
        if (!CollectionUtils.isEmpty(accountQuery.getRoleIdList())) {
            List<Integer> roleIdList = accountQuery.getRoleIdList();
            RoleQuery roleQuery = new RoleQuery();
            if (null != accountQuery.getIndustryId()) {
                roleQuery.setIndustryIdList(Arrays.asList(accountQuery.getIndustryId()));
            }
            roleQuery.setType(RoleTypeEnum.SUPPER_MANAGER.getCode());
            roleQuery.setGrade(BusinessType.INDUSTRY.getCode());
            List<Role> supperAdminRoleList = roleService.getRoleList(null, roleQuery);
            List<Integer> supperAdminRoleIds = supperAdminRoleList.stream().map(Role::getId).collect(Collectors.toList());
            Boolean containSupperAdmin = false;
            for (Integer roleId : supperAdminRoleIds) {
                if (roleIdList.contains(roleId)) {
                    containSupperAdmin = true;
                    break;
                }
            }
            if (containSupperAdmin) {
                List<Integer> supperAccountIdList = accountRoleService.findByRoleId(supperAdminRoleIds);
                if (CollectionUtils.isEmpty(accountQuery.getOrSuperManagerIds())) {
                    accountQuery.setOrSuperManagerIds(supperAccountIdList);
                    return accountQuery;
                } else {
                    List<Integer> orSuperManagerIds = accountQuery.getOrSuperManagerIds();
                    supperAccountIdList.addAll(orSuperManagerIds);
                    accountQuery.setOrSuperManagerIds(supperAccountIdList);
                    return accountQuery;
                }
            }
        }
        if (!CollectionUtils.isEmpty(accountQuery.getIdList())) {
            List<Integer> idList = accountQuery.getIdList();
            //如果存在超管数据，则将其筛选出来
            List<Integer> supperAdminIds = getAdminAccountDynamic(RoleTypeEnum.SUPPER_MANAGER.getCode(), BusinessType.INDUSTRY.getCode(), idList);
            if (!CollectionUtils.isEmpty(supperAdminIds)) {
                if (!CollectionUtils.isEmpty(accountQuery.getOrSuperManagerIds())) {
                    List<Integer> orSuperManagerIds = accountQuery.getOrSuperManagerIds();
                    orSuperManagerIds.addAll(supperAdminIds);
                }
                accountQuery.setOrSuperManagerIds(supperAdminIds);

            }
        }

        //需要企业管理员 并集
        if (accountQuery.getNeedEnterpriseAdmin()) {
            List<Integer> entIds = new ArrayList<>();
            if (!CollectionUtils.isEmpty(accountQuery.getEnterpriseIdList())) {
                entIds.addAll(accountQuery.getEnterpriseIdList());
            }
            if (!CollectionUtils.isEmpty(accountQuery.getProjectIdList())) {
                List<Integer> projectIdList = accountQuery.getProjectIdList();
                QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
                projectQueryWrapper.in("id", projectIdList);
                List<Project> projects = projectDao.selectList(projectQueryWrapper);
                List<Integer> entIdList = projects.stream().map(e -> e.getEnterpriseId()).collect(Collectors.toList());
                entIds.addAll(entIdList);
            }
            if (!CollectionUtils.isEmpty(entIds)) {
                List<Integer> accountIds = enterpriseAdminAccount(entIds);
                if (!CollectionUtils.isEmpty(accountQuery.getIdList())) {
                    accountIds.addAll(accountQuery.getIdList());
                }
                accountQuery.setIdList(accountIds);

            }
        }
        //需要超级管理员 并集
        if (accountQuery.getNeedSuperAdmin()) {
            List<Short> industryIdsResult = new ArrayList<>();
            if (null != accountQuery.getIndustryId()) {
                industryIdsResult.add(accountQuery.getIndustryId());
            }
            if (!CollectionUtils.isEmpty(accountQuery.getEnterpriseIdList())) {
                List<Integer> enterpriseIdList = accountQuery.getEnterpriseIdList();
                QueryWrapper<Enterprise> enterpriseQueryWrapper = new QueryWrapper<>();
                enterpriseQueryWrapper.in("id", enterpriseIdList);
                List<Enterprise> enterprises = enterpriseDao.selectList(enterpriseQueryWrapper);
                List<Short> industryIds = enterprises.stream().map(Enterprise::getIndustryId).collect(Collectors.toList());
                industryIdsResult.addAll(industryIds);
            }
            if (!CollectionUtils.isEmpty(accountQuery.getProjectIdList())) {
                List<Integer> projectIdList = accountQuery.getProjectIdList();
                QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
                projectQueryWrapper.in("id", projectIdList);
                List<Project> projects = projectDao.selectList(projectQueryWrapper);
                List<Short> industryIds = projects.stream().map(Project::getIndustryId).collect(Collectors.toList());
                industryIdsResult.addAll(industryIds);
            }
            if (!CollectionUtils.isEmpty(industryIdsResult)) {
                industryIdsResult = industryIdsResult.stream().distinct().collect(Collectors.toList());
                List<Integer> accountIds = superAdminAccount(industryIdsResult);
                if (CollectionUtils.isEmpty(accountQuery.getOrSuperManagerIds())) {
                    accountQuery.setOrSuperManagerIds(accountIds);
                } else {
                    List<Integer> orSuperManagerIds = accountQuery.getOrSuperManagerIds();
                    orSuperManagerIds.addAll(accountIds);
                    accountQuery.setOrSuperManagerIds(orSuperManagerIds);
                }
            }
        }


        //是否需要 普通内置角色账号
        if (!accountQuery.getNeedCommonInitialized()) {
            //把内置角色ids查找出来
            List<Short> industryIds = new ArrayList<>();
            if (null != accountQuery.getIndustryId()) {
                industryIds.add(accountQuery.getIndustryId());
            }
            List<Integer> commonInitializedRoles = roleService.getCommonInitializedRoles(industryIds);
            if (!CollectionUtils.isEmpty(commonInitializedRoles)) {
                List<Integer> accountIds = accountRoleService.findByRoleId(commonInitializedRoles);
                List<Integer> excludeIdList = new ArrayList<>();
                excludeIdList.addAll(accountIds);
                if (!CollectionUtils.isEmpty(accountQuery.getExcludeIdList())) {
                    excludeIdList.addAll(accountQuery.getExcludeIdList());
                }
                if (null != accountQuery.getExcludeId()) {
                    excludeIdList.add(accountQuery.getExcludeId());
                }
                accountQuery.setExcludeIdList(excludeIdList);
            }
        }
        //条件各种拼接之后，进行统一去重优化

        if (!CollectionUtils.isEmpty(accountQuery.getIdList())) {
            List<Integer> idList = accountQuery.getIdList();
            if (null != accountQuery.getId()) {
                idList.add(accountQuery.getId());
            }
            List<Integer> inIds = idList.stream().distinct().collect(Collectors.toList());
            accountQuery.setIdList(inIds);
        }

        if (!CollectionUtils.isEmpty(accountQuery.getExcludeIdList())) {

            List<Integer> excludeIdList = accountQuery.getExcludeIdList();
            if (null != accountQuery.getExcludeId()) {
                excludeIdList.add(accountQuery.getExcludeId());
            }
            List<Integer> notInIds = excludeIdList.stream().distinct().collect(Collectors.toList());
            accountQuery.setExcludeIdList(notInIds);
        }

        if (accountQuery.getNeedProjectPerson()) {
            //排除超管
            List<Integer> idList = accountQuery.getIdList();
            if (!CollectionUtils.isEmpty(idList)) {
                List<Integer> enterAdminIds = getAdminAccountDynamic(RoleTypeEnum.SUPPER_MANAGER.getCode(), BusinessType.ENTERPRISE.getCode(), idList);
                idList.removeAll(enterAdminIds);
                List<Integer> inIds = idList.stream().distinct().collect(Collectors.toList());
                accountQuery.setIdList(inIds);
            }
        }

        return accountQuery;
    }

    public void accountLogRecord(Account operateAccount, LogOperationTypeEnum logOperationTypeEnum, String operateContent) {
        OperateLog operateLog = new OperateLog();
        operateLog.setMenu(ModuleTypeEnum.ACCOUNT_MANAGE.getName());
        operateLog.setOperateType(logOperationTypeEnum.getType());
        operateLog.setOperateContent(operateContent);
        operateLog.setIp(ThreadLocalUtil.getIp());
        operateLog.setIndustryId(ThreadLocalUtil.getIndustryId());
        if (null == operateAccount) {
            operateAccount = ThreadLocalUtil.getAccount();
        }
        if (null != operateAccount) {
            operateLog.setIndustryId(operateAccount.getIndustryId());
            operateLog.setAccountId(operateAccount.getId());
            operateLog.setLoginName(operateAccount.getLoginName());
            operateLog.setName(operateAccount.getName());
            //填充企业ids+项目ids
            List<Enterprise> enterprises = enterpriseService.list(null,operateAccount);
            if (!org.springframework.util.CollectionUtils.isEmpty(enterprises)){
                operateLog.setEnterpriseIds(enterprises.stream().map(Enterprise::getId).collect(Collectors.toList()));
            }
            List<AccountDetailDTO> projectInfoList = accountService.getAccountProjectInfoByIdList(Collections.singletonList(operateAccount.getId()));
            operateLog.setProjectIds(projectInfoList.stream().map(AccountDetailDTO::getProjectId).collect(Collectors.toList()));
            if (!org.springframework.util.CollectionUtils.isEmpty(projectInfoList)){
                operateLog.setProjectIds(projectInfoList.stream().map(AccountDetailDTO::getProjectId).collect(Collectors.toList()));
            }
        }
        logTemplate.addOperateLog(operateLog);
    }

    /**
     * 保存账号和项目的关系
     *
     * @param projectIds
     * @param accountId
     */
    private void saveAccountProject(List<Integer> projectIds, Integer accountId) {
        //再更新
        List<AccountProject> accountProjectList = new ArrayList<>(projectIds.size());
        for (Integer projectId : projectIds) {
            AccountProject accountProject = new AccountProject();
            accountProject.setAccountId(accountId);
            accountProject.setProjectId(projectId);
            accountProjectList.add(accountProject);
        }
        accountProjectService.saveBatch(accountProjectList);
    }

    /**
     * 保存账号企业关系，通过项目ids
     *
     * @param accountId
     * @param projectIds
     */
    private void saveAccountOrganizationProjectIds(List<Integer> projectIds, Integer accountId) {
        QueryWrapper<Project> proQueryWrapper = new QueryWrapper<>();
        proQueryWrapper.in("id", projectIds);
        List<Project> proList = projectDao.selectList(proQueryWrapper);
        //新增 账号-组织关联表
        saveAccountOrganizationProject(proList, accountId);
    }


    /**
     * 保存帐号与项目的关系
     *
     * @param projects
     * @param accountId
     */
    private void saveAccountOrganizationProject(List<Project> projects, Integer accountId) {
        if (CollectionUtils.isEmpty(projects)) {
            return;
        }
        List<AccountOrganization> accountOrganizationsList = new ArrayList<>();
        for (Project project : projects) {
            AccountOrganization accountOrganization = new AccountOrganization();
            accountOrganization.setAccountId(accountId);
            accountOrganization.setOrganizationId(project.getOrganizationId());
            accountOrganization.setEnterpriseId(project.getEnterpriseId());
            accountOrganization.setType(OrganizationTypeEnum.PROJECT.id.intValue());
            accountOrganizationsList.add(accountOrganization);
        }
        accountOrganizationService.saveBatch(accountOrganizationsList);
    }

    /**
     * 保存帐号与企业的关系
     *
     * @param enterprises
     * @param accountId
     */
    private void saveAccountOrganizationEnterprise(List<Enterprise> enterprises, Integer accountId) {
        if (CollectionUtils.isEmpty(enterprises)) {
            return;
        }
        List<AccountOrganization> accountOrganizationsList = new ArrayList<>();
        for (Enterprise enterprise : enterprises) {
            AccountOrganization accountOrganization = new AccountOrganization();
            accountOrganization.setAccountId(accountId);
            accountOrganization.setOrganizationId(enterprise.getOrganizationId());
            accountOrganization.setEnterpriseId(enterprise.getId());
            accountOrganization.setType(OrganizationTypeEnum.ENTERPRISE.id.intValue());
            accountOrganizationsList.add(accountOrganization);
        }
        accountOrganizationService.saveBatch(accountOrganizationsList);
    }

    /**
     * 仅为奥莱主数据同步定制需求更新员工信息使用
     *
     * @param account
     * @return
     */
    @Override
    public void updateByAccountID(Account account) {
        if (StringUtils.isNotEmpty(account.getPassword())) {
            Account accountNew = accountService.getById(account.getId());
            if (accountNew != null) {
                accountNew.setPassword(account.getPassword());
                accountService.updateById(accountNew);
            }
        }
    }

    @Override
    @Transactional
    public ResultJson<List<AccountDTO>> managersByAccountId(String loginName, Integer developId,Integer enterpriseId) {
        if (null == loginName) {
            return ResultJson.fail("参数错误");
        }
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("login_name", loginName);
        queryWrapper.eq("develop_id", developId);
        Account account = accountDao.selectOne(queryWrapper);
        if (null == account) {
            return ResultJson.fail("账号不存在");
        }
        QueryWrapper<StaffOrganization> staffOrganizationQueryWrapper = new QueryWrapper<>();
        staffOrganizationQueryWrapper.eq("account_id", account.getId());
        staffOrganizationQueryWrapper.eq("enterprise_id",enterpriseId);
        List<StaffOrganization> staffOrganizations = staffOrganizationService.list(staffOrganizationQueryWrapper);
        List<AccountDTO> accountDTOS = new ArrayList<>();
        if (!staffOrganizations.isEmpty()) {
            List<Integer> organizationIds = staffOrganizations.stream().map(i -> i.getOrgId()).distinct().collect(Collectors.toList());
            QueryWrapper<OrganizationManager> organizationManagerQueryWrapper = new QueryWrapper<>();
            organizationManagerQueryWrapper.in("org_id", organizationIds);
            List<OrganizationManager> organizationManagers = organizationManagerService.list(organizationManagerQueryWrapper);
            if (!organizationManagers.isEmpty()) {
                List<Integer> accountIds = organizationManagers.stream().map(i -> i.getAccountId()).distinct().collect(Collectors.toList());
                AccountQuery accountQuery = new AccountQuery();
                accountQuery.setIdList(accountIds);
                accountDTOS = accountDao.getListWithAuth(accountQuery);
            }
        }
        return ResultJson.success(accountDTOS);
    }

    @Override
    public ResultJson<Account> findHigherUp(String loginName, Integer grade, Integer developId,Integer enterpriseId) {
        if (null == loginName || null == grade) {
            return ResultJson.fail("参数错误");
        }
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("login_name", loginName);
        queryWrapper.eq("develop_id", developId);
        Account account = accountDao.selectOne(queryWrapper);
        if (null == account) {
            return ResultJson.fail("账号不存在");
        }
        Integer higherUpId = account.getId();
        for (int i = 0; i <= grade; i++) {
            QueryWrapper<StaffOrganization> staffOrganizationQueryWrapper = new QueryWrapper<>();
            staffOrganizationQueryWrapper.eq("account_id",higherUpId);
            staffOrganizationQueryWrapper.eq("enterprise_id",enterpriseId);
            List<StaffOrganization> staffOrganizations = staffOrganizationService.list(staffOrganizationQueryWrapper);
            if (staffOrganizations.isEmpty()){
                return ResultJson.success();
            }
            QueryWrapper<Staff> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("id", staffOrganizations.get(0).getStaffId());
            Staff staff = staffService.getOne(queryWrapper1);
            if (null == staff) {
                return ResultJson.success();
            }
            higherUpId = staff.getHigherUp();
        }
        Account higherUpAccount = accountDao.selectById(higherUpId);
        if (null != higherUpAccount) {
            higherUpAccount.setPassword("");
        }
        return ResultJson.success(higherUpAccount);
    }

    @Override
    public ResultJson checkAccount(List<String> loginNames, Integer developId) {
        if (null == loginNames) {
            return ResultJson.fail("参数错误");
        }
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("login_name", loginNames);
        queryWrapper.eq("develop_id", developId);
        List<Account> accounts = accountDao.selectList(queryWrapper);
        if (!accounts.isEmpty()){
            for (Account account : accounts){
                if (account.getIsDeleted() || 0 == account.getStatus() ){
                    return ResultJson.success(false);
                }
            }
        }
        return ResultJson.success(true);
    }

    @Override
    public AccountDetailVO getDetail(AccountQuery accountQuery) {
        if (null != accountQuery.getId()) {
            return this.getDetail(null, null, accountQuery.getId());
        } else if (!StringUtils.isEmpty(accountQuery.getLoginName())) {
            // 通过 loginName 获取帐号
            QueryWrapper<Account> accountQueryWrapper = new QueryWrapper<>();
            accountQueryWrapper.eq("login_name", accountQuery.getLoginName());
            accountQueryWrapper.eq("is_deleted", false);
            if (null == accountQuery.getDevelopId()) {
                accountQueryWrapper.eq("develop_id", developerService.getDefault().getId());
            } else {
                accountQueryWrapper.eq("develop_id", accountQuery.getDevelopId());
            }

            Account account = accountDao.selectOne(accountQueryWrapper);
            if (null == account) {
                log.warn("帐号不存在");
                return null;
            }
            AccountDetailVO accountDetailVO = new AccountDetailVO();
            BeanUtils.copyProperties(account, accountDetailVO);

            // 获取角色信息
            List<Role> roles = roleService.getRoleListByAccountId(account.getId());
            if (!CollectionUtils.isEmpty(roles)) {
                accountDetailVO.setRoleIds(roles.stream().map(i -> i.getId()).collect(Collectors.toList()));
            }
            return accountDetailVO;
        } else {
            log.warn("查询帐号详情失败，参数错误");
            return null;
        }
    }

    @Override
    public List<Account> listByDeveloperId(Integer developerId) {
        return accountDao.selectList(new QueryWrapper<Account>().eq("develop_id",developerId));
    }

    @Override
    public List<AccountDTO> getListByRoleIds(List<Integer> roleIds) {
        if (roleIds.isEmpty()){
            return null;
        }
        QueryWrapper<AccountRole> accountRoleQueryWrapper = new QueryWrapper<>();
        accountRoleQueryWrapper.in("role_id",roleIds);
        List<AccountRole> accountRoles = accountRoleService.list(accountRoleQueryWrapper);
        if (accountRoles.isEmpty()){
            return null;
        }
        List<Integer> accountIds = accountRoles.stream().distinct().map(AccountRole::getAccountId).collect(Collectors.toList());
        AccountQuery accountQuery = new AccountQuery();
        accountQuery.setIdList(accountIds);
        List<AccountDTO> accountDTOS = getList(accountQuery);
        return accountDTOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultJson register(App app,Short industryId,AccountRegisterDTO accountRegisterDTO) {
        //手机号校验
        CentDataVerifyUtil.phoneVerify(accountRegisterDTO.getPhone());
        QueryWrapper<Account> accountQueryWrapper = new QueryWrapper<>();
        accountQueryWrapper.select("id");
        accountQueryWrapper.eq("develop_id", app.getDevelopId());
        accountQueryWrapper.eq("is_deleted", false);
        accountQueryWrapper.eq("phone", accountRegisterDTO.getPhone());
        List<Account> accountList = accountDao.selectList(accountQueryWrapper);
        if (accountList.size() > 0) {
            log.warn("手机号码已存在 {}", accountRegisterDTO.getPhone());
            throw new DataException("手机号信息已存在");
        }
        if (null != accountRegisterDTO.getVerifyCode()){
            //验证码校验
            ResultJson resultJson = messageCodeService.phoneMsgCodeVerify(industryId.toString(), accountRegisterDTO.getPhone(), accountRegisterDTO.getVerifyCode(), false);
            if (!CodeEnum.SUCCESS.getCode().equals(resultJson.getCode())) {
                return resultJson;
            }
        }
        //创建账号
        Account account = new Account();
        account.setPhone(accountRegisterDTO.getPhone());
        //设置初始密码
        account.setPassword(DEFAULT_PWD);
        account.setPassword(encode(account));
        //设置默认开发者
        account.setDevelopId(app.getDevelopId());
        //设置登录名
        account.setLoginName(UUID.randomUUID().toString().replaceAll("-", ""));
        account.setType((short) 1);
        account.setCertification(false);
        account.setIsLogged(true);

        accountDao.insert(account);

        //设置游客角色
        List<Short> industryIds = Collections.singletonList(industryId);
        RoleQuery roleQuery = new RoleQuery();
        roleQuery.setCode(REGISTER_TOURIST_ROLE_CODE);
        roleQuery.setIndustryIdList(industryIds);
        Role role = roleService.getRole(roleQuery);
        if (null == role) {
            throw new BusinessException("当前平台，没有定义对应角色");
        }
        //添加角色
        addRole(account.getId(),Collections.singletonList(role.getId()));
        accountLogRecord(null, LogOperationTypeEnum.REGISTER, "注册账号" + "【" + account.getId() + "】");
        return ResultJson.success("操作成功", account.getId());
    }

    @Override
    public List<Integer> getEnterpriseIds(Integer id) {
        if(null == id){
            throw new DataException("参数错误");
        }
        QueryWrapper<AccountOrganization> accountOrganizationQueryWrapper = new QueryWrapper<>();
        accountOrganizationQueryWrapper.select("enterprise_id");
        accountOrganizationQueryWrapper.eq("account_id", id);
        accountOrganizationQueryWrapper.last("group by enterprise_id");
        List<AccountOrganization> accountOrganizations = accountOrganizationDao.selectList(accountOrganizationQueryWrapper);
        return accountOrganizations.stream().map(i -> i.getEnterpriseId()).collect(Collectors.toList());
    }

    /**
     * 密码明文推送MQ
     * @param account
     * @param pwd
     */
    private void sendPwdToMQ(Account account, String pwd) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("accountId", account.getId());
        jsonObject.put("password", pwd);
        log.info("jsonObject：{}", jsonObject.toJSONString());
        accountPwdProducer.updateAccountPwdTopic(jsonObject.toJSONString());
    }

    /**
     * 批量授权
     * @param permissionGroupDTO
     * @return
     */
    @Override
    public ResultJson batchAuth(PermissionGroupDTO permissionGroupDTO) {
        if (null == permissionGroupDTO.getEnterpriseId()){
            return ResultJson.fail("参数错误");
        }
        if (null == permissionGroupDTO.getAccountIds()){
            return ResultJson.success();
        }
        //去重
        List<Integer> accountIds = permissionGroupDTO.getAccountIds().stream().distinct().collect(Collectors.toList());
        List<PermissionGroup> permissionGroups = new ArrayList<>();
        List<Integer> roleId = new ArrayList<>();
        List<Integer> projectId = new ArrayList<>();
        for (Integer integer : accountIds){
            for (PermissionGroupDTO permissionGroupDTO1 : permissionGroupDTO.getPermissionGroupDTOS()){
                List<Integer> roleIds = permissionGroupDTO1.getRoleList();
                if (org.apache.commons.collections4.CollectionUtils.isEmpty(roleIds)) {
                    throw new BusinessException("缺少角色信息");
                }
                PermissionGroup permissionGroup = new PermissionGroup();
                permissionGroup.setAccountId(integer);
                permissionGroup.setEnterpriseId(permissionGroupDTO.getEnterpriseId());
                roleIds = permissionGroupDTO1.getRoleList().stream().distinct().collect(Collectors.toList());
                roleId.addAll(roleIds);
                permissionGroup.setRoleIds(Joiner.on(",").skipNulls().join(roleIds));
                if (!permissionGroupDTO1.getProjectList().isEmpty()){
                    List<Integer> projectIds = permissionGroupDTO1.getProjectList().stream().distinct().collect(Collectors.toList());
                    permissionGroup.setProjectIds(Joiner.on(",").skipNulls().join(projectIds));
                    projectId.addAll(projectIds);
                }
                permissionGroups.add(permissionGroup);
            }
        }
        if (permissionGroupDTO.getIsCover()){
            //覆盖授权 先删后增
            QueryWrapper<PermissionGroup> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("account_id",permissionGroupDTO.getAccountIds());
            queryWrapper.eq("enterprise_id",permissionGroupDTO.getEnterpriseId());
            List<PermissionGroup> permissionGroupList = permissionGroupService.list(queryWrapper);
            permissionGroupService.remove(queryWrapper);
            //删除 账号-项目、账号-角色关联表
            if (!permissionGroupList.isEmpty()){
                for (PermissionGroup permissionGroup :permissionGroupList){
                    List<Integer> roleIds = Arrays.stream(permissionGroup.getRoleIds().split(",")).map(Integer::valueOf).collect(Collectors.toList());
                    List<Integer> projectIds = new ArrayList<>();
                    if (null != permissionGroup.getProjectIds()){
                        projectIds =Arrays.stream(permissionGroup.getProjectIds().split(",")).map(Integer::valueOf).collect(Collectors.toList());
                        accountProjectService.delete(Collections.singletonList(permissionGroup.getAccountId()),projectIds);
                    }
                    accountRoleService.deleteAccountRole(Collections.singletonList(permissionGroup.getAccountId()),roleIds);
                }
            }
        }
        //保存sdata_account_role 和 sdata_account_project
        for (Integer integer : accountIds){
            accountRoleService.insertAccountRole(integer,roleId);
            accountProjectService.insert(integer,projectId);
        }
        permissionGroupService.saveBatch(permissionGroups);
        return ResultJson.success();
    }
}
